您可以查看字节码以获得洞察力:
0: new #16 // class SomeClass
3: dup
4: invokespecial #18 // Method SomeClass."":()V
7: invokevirtual #19 // Method SomeClass.longMethod:()V
> new实际分配对象,对象的引用被推入堆栈.
> dup复制堆栈顶部;现在,前两个堆栈项是对新创建的对象的引用.
> invokespecial在这里调用SomeClass的构造函数,弹出堆栈;现在,堆栈只包含对SomeClass实例的单个引用.该实例未进行GCed,因为堆栈上存在对它的引用.
> invokevirtual在这里调用longMethod.同样,实例不是GCed,因为对它的引用仍然存在于堆栈上(并且在方法完成后弹出,之后它符合GC的条件).
(new SomeClass()).longMethod();
是不一样的
{
// very local scope
SomeClass throwAwayRef = new SomeClass();
throwAwayRef.longMethod();
}
在字节码级别,因为后者涉及一个astore和aload.但是,这两者肯定在功能上是等价的. longMethod完成后,SomeClass实例仍符合GC的条件(执行invokevirtual时,两个代码段的堆栈看起来相同).
参考: