代码之家  ›  专栏  ›  技术社区  ›  iandisme

这两个Java段的性能有什么不同吗?

  •  2
  • iandisme  · 技术社区  · 14 年前

    SomeObject myObj = new SomeObject();
    myObj.doSomething();
    

    与。

    new SomeObject().doSomething();
    
    7 回复  |  直到 13 年前
        1
  •  5
  •   Rekin    14 年前

    查看生成的字节码:

    // code 1
    new SomeObject().doSomething();
    
    // bytecode 1
       0:   new #2; //class SomeObject
       3:   dup
       4:   invokespecial   #3; //Method SomeObject."<init>":()V
       7:   invokevirtual   #4; //Method SomeObject.doSomething:()V
       10:  return
    

    您可以清楚地看到,这个还有两个说明:

    // code 2
    SomeObject myObj = new SomeObject();
    myObj.doSomething();
    
    // bytecode 2
       0:   new #2; //class SomeObject
       3:   dup
       4:   invokespecial   #3; //Method SomeObject."<init>":()V
       7:   astore_1
       8:   aload_1
       9:   invokevirtual   #4; //Method SomeObject.doSomething:()V
       12:  return
    

    这些指令看起来非常多余,很容易优化。我敢打赌JIT编译器会在需要时处理它们。

        2
  •  4
  •   Tassos Bassoukos    14 年前

    差别正好是2个JVM字节码,它转换成1条额外的机器指令,JIT可能会优化掉这些指令(如果您不使用变量做任何其他事情的话)。

        3
  •  2
  •   unbeli    14 年前

    不。

        4
  •  1
  •   Sniggerfardimungus    14 年前

        5
  •  1
  •   Mattias Nilsson    14 年前

    虽然生成的字节码可能不同,但我认为这应该是jit编译器更容易优化的事情之一。根据它的实际功能,甚至对象创建也可以完全优化。

        6
  •  0
  •   rsp    14 年前

    两者之间唯一的区别是只要 myObj path to root 分配的对象将不会被垃圾收集。

        7
  •  0
  •   Jay    14 年前

    第一个例子的效率略低。在第一个示例中,对象引用将一直保持到函数或封闭块结束。在第二个示例中,一旦调用完成,对象引用将可用于垃圾收集。当然,它实际上可能不是垃圾收集的。

    我还没有检查生成的字节码。Java保存引用的方式可能有所不同,但无论哪种情况,我都怀疑它微不足道。