从基本结构到Java 7新特性(3)

发表于:2013-01-05来源:ImportNew作者:朱伟杰点击数: 标签:java
invokeinterface:调用一个接口方法在这段Java汇编代码中,addUser()方法是在第四行的5:invokevitual#23进行调用的。这表示对应索引为23的方法会被调用。索引为23的

  invokeinterface:调用一个接口方法在这段Java汇编代码中,addUser()方法是在第四行的“5:invokevitual#23″进行调用的。这表示对应索引为23的方法会被调用。索引为23的方法的名称已经被javap给注解在旁边了。invokevirtual是Java字节码里调用方法的最基本的操作码。在Java字节码里,有四种操作码可以用来调用一个方法,分别是:invokeinterface,invokespecial,invokestatic以及invokevirtual。操作码的作用分别如下:

  invokespecial: 调用一个初始化方法,私有方法或者父类的方法

  invokestatic:调用静态方法

  invokevirtual:调用实例方法

  Java字节码的指令集由操作码和操作数组成。类似invokevirtual这样的操作数需要2个字节的操作数。

  用更新的类库来编译上面的应用代码,然后反编译它,将会得到下面的结果。

1
2
3
4
5
6
7
8
public void add(java.lang.String);
  Code:
   0:   aload_0
   1:   getfield        #15; //Field admin:Lcom/nhn/user/UserAdmin;
   4:   aload_1
   5:   invokevirtual   #23; //Method com/nhn/user/UserAdmin.addUser:(Ljava/lang/String;)Lcom/nhn/user/User;
   8:   pop
   9:   return

  你会发现,对应索引为23的方法被替换成了一个返回值为”Lcom/nhn/user/User”的方法。

  在上面的反汇编代码里,代码前面的数字代码什么呢?

  它表示的是字节数。大概这就是为什么运行在JVM上面的代码成为Java“字节”码的原因。简而言之,Java字节码指令的操作码,例如aload_0,getfield和invokevirtual等,都是用一个字节的数字来表示的(aload_0=0x2a,getfield=0xb4,invokevirtual=0xb6)。由此可知Java字节码指令的操作码最多有256个。

  aload_0和aload_1这样的指令不需要任何操作数。因此,aload_0指令的下一个字节是下一个指令的操作码。不过,getfield和invokevirtual指令需要2字节的操作数。因此,getfiled的下一条指令是跳过两个字节,写在第四个字节的位置上的。十六进制编译器里查看字节码的结果如下所示。

1
2a b4 00 0f 2b b6 00 17 57 b1

  表一:Java字节码中的类型表达式在Java字节码里,类的实例用字母“L;”表示,void 用字母“V”表示。通过这种方式,其他的类型也有对应的表达式。下面的表格对此作了总结。

Java Bytecode Type Description
B byte signed byte
C char Unicode character
D double double-precision floating-point value
F float single-precision floating-point value
I int integer
J long long integer
L<classname> reference an instance of class <classname>
S short signed short
Z boolean true or false
[ reference one array dimension

原文转自:http://www.ltesting.net