编码:
public class Foo {
public byte[] bar = new byte[3];
}
编译为相同:
class Foo2 {
public byte[] bar;
public Foo2() {
this.bar = new byte[3];
}
}
这里没有“文字”,字段初始化程序和初始化程序块只是被添加到每个构造函数的代码之前(我认为是源代码顺序)——您要查找的信息不会被保留。您必须查看那些构造函数的反编译代码并以某种方式对其进行分析,但这将是模棱两可的。
此构造函数的操作码是:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_3
6: newarray byte
8: putfield #2; //Field bar:[B
11: return
索引 4 到 8 对应于行this.bar = new byte[3];
。它们的大致意思是:
- 将
this
引用压入堆栈。
- 将整数压
3
入堆栈。
- 弹出
3
堆栈顶部的整数(the),创建该长度的字节数组,将数组压入堆栈。
- 将堆栈顶部的值(字节数组)设置为堆栈顶部倒数
bar
第二个对象的字段#2(即 )的值(this
)。(另外,将这两个从堆栈中弹出。)
这并不能很好地映射到原始 Java 源代码;如您所见,对应于“new byte[3]”的部分被插入到实现“this.bar = ...”的部分中间,即使对于像这样简单的表达式,事情也会发生混乱。从字节码重构语句可能不会是微不足道的——它们没有明确分隔,当你从堆栈中弹出所有内容时,语句就结束了。