龙空技术网

Java字节码指令:new(0xBB)

IT狂想者 35

前言:

此刻兄弟们对“newjava”都比较关注,你们都想要了解一些“newjava”的相关文章。那么小编同时在网络上网罗了一些有关“newjava””的相关知识,希望大家能喜欢,小伙伴们快快来了解一下吧!

new 是 Java 字节码中的一条指令。它用于创建一个新的对象实例。它在堆内存中分配对象所需的内存,并将对这个新对象的引用压入操作数栈顶。该指令并不调用构造函数,实际的对象初始化是在后续的 invokespecial 指令中完成的。

new(操作码) + n(操作数)

操作码:0xBB操作数:一个无符号的 16 位整数(范围 0 到 65,535 ),表示一个常量池索引。功能:用于创建一个新的对象实例。工作原理:解析操作数:根据操作数中的索引,从常量池中加载一个 CONSTANT_Class 条目,这个条目描述了要创建的类。类验证:JVM 验证类是否加载,是否可被实例化(例如,类是否是抽象类,是否有有效的构造函数等)。分配内存:在堆内存中为新对象分配足够的内存。初始化:将对象的所有字段初始化为默认值(如 0、null、false),然后调用类的构造函数(即 <init> 方法)进行进一步初始化。压栈:将新创建的对象的引用压入操作数栈,以便后续的操作可以使用这个引用。

使用示例

假设我们有以下Java代码:

public void exampleMethod() {    Object obj = new Object();}

编译成字节码后,相关部分可能如下:

0: new #1           // 创建一个新的对象3: dup              // 复制栈顶的对象引用,因为后续需要它来调用构造函数4: invokespecial #3 // 调用 Example 类的构造函数7: astore_1         // 将对象引用存储到局部变量表中7: return           // 方法结束,返回

解释:

new #1:new 指令分配内存空间以创建一个 Object 类的实例,但未初始化。在这个示例中,#1 是常量池中 java/lang/Object对象引用的索引。dup:将栈顶的对象引用复制一份并推入栈中。目的是为了在之后invokespecial调用构造函数消耗一个对象引用后,栈中仍然保留着一个对该对象的引用。invokespecial #2:调用 Object 类的构造函数 "<init>"。会消耗操作数栈顶的一个对象引用。astore_1:将栈顶的对象引用存储在局部变量表中的位置 1(obj)return:结束方法的执行并返回(由于方法的返回类型为 void,不需要返回值)。

标签: #newjava