首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

【ASM系列二】字节码介绍

2012-09-04 
【ASM系列2】字节码介绍从一个简单的例子开始看,写一个类:然后来到.class文件的目录下,执行javap -verbose -

【ASM系列2】字节码介绍

           从一个简单的例子开始看,写一个类:

           【ASM系列二】字节码介绍

           然后来到.class文件的目录下,执行javap -verbose -c Main,verbose参数的作用是指定javap显示常量池,而-c的作用是指定javap显示方法的字节码。执行结果如下:

                    【ASM系列二】字节码介绍

           其中第一部分是常量池,从来保存例如字符串、类名、方法名等常量项,这些常量项又有着固定的格式。首先,每个常量项都有一个标识,例如字符串是Asciz,类是class,方法是Method。而常量项又可以包含其他常量项,比如Method常量项就包含一个class常量项和方法的NameAndType常量项,而class常量又包含类名的字符串常量项,方法的NameAndType常量项又包含方法名的字符串常量项和方法签名的字符串常量项。

           下面是每个方法的描述,第一个是Main方法的构造函数,这里我们也可以指定,类中没有显示写构造函数的时候,jvm会给我们在编译的时候自动生成一个构造函数。它的内容只要三个操作:aload_0、invokespecial #8和return。

           load系列的的字节码作用是把本地变量加载到操作数栈当中。比如:iload、lload、fload、dload等是针对不同的类型的操作码,i表示int,l表示long,f表示fload,d表示double,a表示引用,在java的字节码当中,大部分的操作数据的指令都是这个规律。

          aload_0:aload的意思是从本地变量列表中加载一个引用到操作数栈中,后面的操作数(这里是0)指示了要加载的本地变量的偏移量。在这里指的是加载方法的this本地变量,在实例对象的方法中,第一个本地变量永远是this。此外,在构造函数中,往往第一个字节码都是aload_0,因为紧接着的默认调用是父类的构造器,super方法需要当前实例作为入参。

           invoke系列的字节码包括:invokevirtual、invokeinterface、invokespecial以及invokestatic。invokevirtual是调用对象的成员方法,invokeinterface是调用接口上的方法,invokespecial是指调用类内部的private方法,而invokestatic则是指调用指定类的静态方法。

           在这里,Main类的构造函数中,invokevirtual #8指定了要调用的是常量池第8位表示的方法,即java.lang.Object的初始化方法,并且使用了aload_0这个步骤放到操作数栈顶的this对应引用作为Object构造函数的第一个也是唯一的参数。

          最后看return系列的指令,这系列的指令也是类似得有ireturn、lreturn、freturn、dreturn、areturn,分别和之前讲到load系列的指令里的i、l、f、d、a对应,标识了方法返回不同的类型,而return系列还多了一种类型的指令是return,它表示void类型方法的返回。相比其他有返回值的return,return指令在返回的时候不会去栈中load数据,而其余几个都会在返回之前从操作数栈中获取返回值,其中lreturn和dreturn会稍微特殊,他们需要从操作数栈中弹出两位,其余的几个都只要弹出一位就直接返回了。

           先到这,未完待续。


热点排行