Oracle和Eclipse编译器生成的java字节码的差异

Nik*_*kem 12 java bytecode bytecode-manipulation

我们的项目执行一些Java字节码检测.我们偶然发现了一些奇怪的行为.假设以下代码段:

  public void a() {
    new Integer(2);
  }
Run Code Online (Sandbox Code Playgroud)

Oracle的javac将上面的代码编译成以下字节码:

   0:   new #2; //class java/lang/Integer
   3:   dup
   4:   iconst_2
   5:   invokespecial   #3; //Method java/lang/Integer."<init>":(I)V
   8:   pop
   9:   return
Run Code Online (Sandbox Code Playgroud)

和Eclipse的编译器进入:

   0:   new #15; //class java/lang/Integer
   3:   iconst_2
   4:   invokespecial   #17; //Method java/lang/Integer."<init>":(I)V
   7:   return
Run Code Online (Sandbox Code Playgroud)

如您所见,Oracle编译器在"new"之后生成"dup",而Eclipse则不然.在这个用例中完全正确,因为根本不使用新创建的Integer实例,因此不需要"dup".

我的问题是:

  1. 是否有一些不同编译器之间的差异概述?文章/博客文章?
  2. 我可以安全地得出结论,如果"new"和"invokespecial"之间没有"dup",那么初始化后不会使用对象吗?

Ant*_*pov 6

如果有一个DUP之间新的invokespecial那么对象通常是编译后使用.例如,字段初始化通常是new,dup,invokespecialputfield的序列.但是,在您的示例中,最后一条指令是pop,它清除堆栈中的objectref - 这就是您可以假设不使用此对象的方式.


A.H*_*.H. 3

  1. 我可以安全地得出结论,如果“new”和“invokespecial”之间没有“dup”,那么初始化后不会使用对象吗?

我不确定您的确切意思,但对创建的对象的引用可能会由构造函数存储在某处。因此,调用方法在初始化后可能不会使用该对象,但该对象可能仍然可达,因此可能不可进行垃圾回收。