转载地址

一:Java字节代码的组织形式

  类文件{

  OxCAFEBABE,小版本号,大版本号,常量池大小,常量池数组,访问控制标记,当前类信息,父类信息,实现的接口个数,实现的接口信息数组,域个数,域信息数组,方法个数,方法信息数组,属性个数,属性信息数组

  }

二:查看方法 --- javap命令

  例子:有一个Java类Demo.java

 public class Demo {
private String str1;
private String str2;
private int num1;
private int num2;
public static final String STATIC_DATA = "hello world"; private void sayHello1(){
System.out.println("this is method1...");
}
private void sayHello2(){
System.out.println("this is method2...");
}
public void sayHello3(){
System.out.println("this is method3...");
}
}

通过jdk自带的反编译工具命令 javap 可以查看class文件的字节码信息

 D:\>javap -verbose Demo >> Demo.txt

Demo.txt:

 Compiled from "Demo.java"
public class Demo extends java.lang.Object
SourceFile: "Demo.java"
minor version: 0
major version: 49 Constant pool:
const #1 = class #2; // Demo
const #2 = Asciz Demo;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz str1;
const #6 = Asciz Ljava/lang/String;;
const #7 = Asciz str2;
const #8 = Asciz num1;
const #9 = Asciz I;
const #10 = Asciz num2;
const #11 = Asciz STATIC_DATA;
const #12 = Asciz ConstantValue;
const #13 = String #14; // hello world
const #14 = Asciz hello world;
const #15 = Asciz <init>;
const #16 = Asciz ()V;
const #17 = Asciz Code;
const #18 = Method #3.#19; // java/lang/Object."<init>":()V
const #19 = NameAndType #15:#16;// "<init>":()V
const #20 = Asciz LineNumberTable;
const #21 = Asciz LocalVariableTable;
const #22 = Asciz this;
const #23 = Asciz LDemo;;
const #24 = Asciz sayHello1;
const #25 = Field #26.#28; // java/lang/System.out:Ljava/io/PrintStream;
const #26 = class #27; // java/lang/System
const #27 = Asciz java/lang/System;
const #28 = NameAndType #29:#30;// out:Ljava/io/PrintStream;
const #29 = Asciz out;
const #30 = Asciz Ljava/io/PrintStream;;
const #31 = String #32; // this is method1...
const #32 = Asciz this is method1...;
const #33 = Method #34.#36; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #34 = class #35; // java/io/PrintStream
const #35 = Asciz java/io/PrintStream;
const #36 = NameAndType #37:#38;// println:(Ljava/lang/String;)V
const #37 = Asciz println;
const #38 = Asciz (Ljava/lang/String;)V;
const #39 = Asciz sayHello2;
const #40 = String #41; // this is method2...
const #41 = Asciz this is method2...;
const #42 = Asciz sayHello3;
const #43 = String #44; // this is method3...
const #44 = Asciz this is method3...;
const #45 = Asciz SourceFile;
const #46 = Asciz Demo.java; {
public static final java.lang.String STATIC_DATA;
Constant value: String hello world
public Demo();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #18; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LDemo; public void sayHello3();
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #43; //String this is method3...
5: invokevirtual #33; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 17: 0
line 18: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this LDemo;
}

解析:

  1、版本号 major version: 49 //java版本 jdk1.6显示的是50, jdk1.5显示的是49,jdk1.4显示的是58 , 高版本能执行低版本的class文件

  2、常量池Constant pool

  Method:方法

  Field:字段

  String:字符串

  Asciz:签名如<init>由jvm调用,其他是不能够去调用它的

  NameAndType:变量名的类型

  Class:类

  通过字节码,我们可以看到Demo类 继承于java.lang.Object,如果类中没有显式声明构造函数的话,编译器会插入一个缺省无参的构造函数(构造函数在JVM级别是显示成<init>的普通函数)。

  三:检测代码的效率问题

  学习Java的过程中,都会了解到字符串合并时要用到StringBuffer 来代替String,那下面就来通过Java字节码来验证两种方式的效率性。

  例子:一个Java类 TestString.java

 <strong>public class TestString {
public String testString(String str1, String str2){
return str1 + str2;
}
public String testStringBuffer(StringBuffer sb, String str){
return sb.append(str).toString();
}
}
</strong>

javap –c TestString 后字节码信息:

Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return public java.lang.String testString(java.lang.String, java.lang.String);
Code:
0: new #16; //class java/lang/StringBuilder
3: dup
4: aload_1
5: invokestatic #18; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
8: invokespecial #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: aload_2
12: invokevirtual #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
18: areturn public java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String);
Code:
0: aload_1
1: aload_2
2: invokevirtual #40; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
5: invokevirtual #45; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
8: areturn
}

从 上面编译后的字节码信息可以看出来,方法testString 调用了五个方法:new 、invokestatic 、invokespecial 和两个invokevirtual ; 而testStringBuffer 方法只调用了两个invokevirtual 方法。第一个方法比第二个方法多做了好多工作,其效率当然是要低的。而且我们从java/lang/StringBuilder.append: (Ljava/lang/String;)Ljava/lang/StringBuilder;

   可以看出来其实对于String字符串合并,内部还是转化为StringBuilder的方法调用,这是因为String是长度不可变的,所以不如直接 采用StringBuilder(与StringBuffer 长度都是可变的,只不过前者是非线程安全,后者是线程安全)进行字符串合并。

 
 

Java之字节码(1) - 深入解析的更多相关文章

  1. Java Class 字节码文件结构详解

    Class字节码中有两种数据类型: 字节数据直接量:这是基本的数据类型.共细分为u1.u2.u4.u8四种,分别代表连续的1个字节.2个字节.4个字节.8个字节组成的整体数据. 表:表是由多个基本数据 ...

  2. 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性

    我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...

  3. java虚拟机字节码执行引擎

    定义 java虚拟机字节码执行引擎是jvm最核心的组成部分之一,它做的事情很简单:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.在不同的虚拟机实现里,执行引擎在执行java代码 ...

  4. 小师妹学JVM之:java的字节码byte code简介

    目录 简介 Byte Code的作用 查看Byte Code字节码 java Byte Code是怎么工作的 总结 简介 Byte Code也叫做字节码,是连接java源代码和JVM的桥梁,源代码编译 ...

  5. 聊聊Java的字节码

    本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 巴山楚水凄凉地,二十三年弃置身.怀旧空吟闻笛赋,到乡翻似烂柯人.沉舟侧畔千帆过,病树前头万木春 ...

  6. java class 字节码

    java class 字节码 协议: class文件 魔数(Magic):4byte -> 0xCAFEBABE 类似2f3f 版本(Version):4Byte -> 0x0000003 ...

  7. 使用java动态字节码技术简单实现arthas的trace功能。

    参考资料 ASM 系列详细教程 编译时,找不到asm依赖 用过[Arthas]的都知道,Arthas是alibaba开源的一个非常强大的Java诊断工具. 不管是线上还是线下,我们都可以用Arthas ...

  8. 从字节码层面,解析 Java 布尔型的实现原理

    最近在系统回顾学习 Java 虚拟机方面的知识,其中想到一个很有意思的问题:布尔型在虚拟机中到底是什么类型? 要想解答这个问题,我们看 JDK 的源码是无法解决源码的,我们必须深入到 class 文件 ...

  9. Java 动态字节码技术

    对 Debug 的好奇 初学 Java 时,我对 IDEA 的 Debug 非常好奇,不止是它能查看断点的上下文环境,更神奇的是我可以在断点处使用它的 Evaluate 功能直接执行某些命令,进行一些 ...

随机推荐

  1. Java反射机制涉及的类常见方法使用总结

    import java.lang.reflect.Constructor; import java.lang.reflect.*; /*Class:代表一个字节码文件的对象,每当有类被加载进内存,JV ...

  2. Markdown 简明语法手册 - 作业

    目录 Cmd Markdown 简明语法手册 1. 内容目录 2. 标签分类 3. 删除线 水平线--- 1. 斜体和粗体 2. 分级标题 标题1 标题2 标题3 3. 外链接 4. 无序列表 5. ...

  3. IOS常用的第三方开发库

    开发几个常用的开源类库及下载地址: 1.json json编码解码2.GTMBase64 base64编码解码3.TouchXML xml解析4.SFHFKeychainUtils 安全保存用户密码到 ...

  4. 【MongoDB】windows下搭建Mongo主(Master)/从(slave)数据库同步

    在前面一系列的文章中.我们讲述了mongodb的基本操作,高级查询以及索引的使用. 该篇博客主要说明在windows系统怎样创建主从数据库同步: 须要启动两个mongoDb文档数据库,一个是主模式启动 ...

  5. XmlnsDefinitionAttribute Is Pretty Nifty

    When we want to declaratively use our custom controls or reference the types we defined in XAML, we ...

  6. 【提醒】使用 iptables 时,特别注意 规则的顺序

    在 centos 上安装 redis 服务器,很快就搞定了,服务器上使用 redis-cl 测试都没有问题了. 但到宿主机上测试,怎么测试都不通过,关键是:关闭了 centos 的 Iptables ...

  7. BigDecimal类型数据保留两位小数即百分比运算

    方法示例: DecimalFormat df = new DecimalFormat("0.00"); Object price = 2; Object price1 = 2.3; ...

  8. mysql重启,重启释放ibtmp1

    1.通过rpm包安装的MySQL service mysqld restart 2.从源码包安装的MySQL // linux关闭MySQL的命令$mysql_dir/bin/mysqladmin - ...

  9. 嵌入式mp3播放器

    分四部分:按键驱动,声卡驱动,Madplay播放器移植,MP3主播放器处理 按键1:播放,按键2:停止,按键3:上一曲,按键4:下一曲 UA1341内核自带声卡驱动 .解压内核: tar zxvf l ...

  10. OpenRISC自定义指令GCC修改

    This short tutorial shows how to use the custom instructions defined by OpenRISC architecture. The O ...