1、针对对象的操作码
实例化一个新对象需要通过new操作码来实现。
对象的创建
操作码
操作数
说明
new
index
在堆中创建一个新的对象,将其引用压入栈
new操作码后面紧跟一个无符号16位数,表示常量池中的一个索引。在特定偏移量位置处的常量池入口给出了新对象所属类的信息。如果还没有这些信息,那么虚拟机会解析这个常量池入口。它会为这个堆中的对象建立一个新的实例,用默认初始化对象实例变量,然后把新对象的引用压入栈。
存取实例变量
操作码
操作数
说明
putfield
index
设置对象字段(由index指定)的值,值value和对象引用objectref均从栈中获得
getfield
index
将对象字段(由index指定)压入栈,对象引用objectref栈中取得
存取类变量
操作码
操作数
说明
putstatic
index
设置静态字段(由index指定)的值,值value从栈中获得
getstatic
index
将静态字段(由index指定)压入栈
putfield和getfield这两个操作码只在字段是实例变量的情况下才执行,putstatic和getstatic对静态变量进行存取操作。操作数表示常量池的索引。这个索引所指向的常量池入口包含了该字段的所属类、名字和类型等信息。如果还没有这些信息,虚拟机会解析这个常量池入口。
例如下面代码:
public class testa {
int x;
int y;
}
public class testmain {
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
testa testa = new testa();
testa.x = 3;
testa.y = 4;
}
}
用javap工具查看其字节码指令为:
compiled from "testmain.java"
public class testmain extends java.lang.object{
public testmain();
code:
0: aload_0
1: invokespecial #8; //method java/lang/object."<init>":()v
4: return
public static void main(java.lang.string[]);
code:
0: new #16; //class testa 新建 testa对象
3: dup //
4: invokespecial #18; //method testa."<init>":()v 调用构造方法
7: astore_1 //存入位置为1的局部变量
8: aload_1 //取出位置为1的局部变量压入栈
9: iconst_3 //常量3入栈
10: putfield #19; //field testa.x:i 赋值
13: aload_1
14: iconst_4
15: putfield #23; //field testa.y:i
18: return
}