假设我的对象状态为private static Integer i = 0
。假设我通过一些将i
作为参数的方法推送出来,如下所示:pushThroughMethod(i)
。
是否i
被复制到堆上并有资格进行垃圾回收?
答案 0 :(得分:1)
Java原始类型(int,long,float等)但不是它们的对象(Integer,Long,Float等)是按值传递的。此外,对象的引用按值传递。虽然对象本身是通过引用传递的。
因此,如果您使用对象O调用方法x(),那么:
O o = new O(); // Create an O on the heap, put a reference to it on the stack
x(o); // Pass a copy of the reference into x, the reference still points to O
X内:
void x(O o) {
// o is a separate reference, so if you do o = null; it does not chance the reference in the calling function.
// but the o itself is shared, so if you do o->doSomething() the calling function will be able to see the results of doSomething().
}
在您调用pushThroughMethod(i)
的示例中,创建了对i
的新引用,但它指向的是Integer
。
i
只有在所有强引用已经消失后才有资格获得垃圾收集。在这种情况下,即使pushThroughMethod()删除它对i
的引用,静态引用仍将保留并阻止收集。
答案 1 :(得分:0)
您已声明了引用类型java.lang.Integer
的变量。无论您分配给它的是对该类型的对象的引用。
显然,无论是否进行任何方法调用,堆上都有一个对象。
相反,如果你有一个int
变量,并且你将它传递给一个带有Integer
参数的方法,那么你会说Integer
个实例将是正确的因为该方法调用而参与其中。
该调用是否构成Integer
的 new 实例是JVM的内部细节,并且至少受到以下问题的限制(对HotSpot 7有效):
Integer
实例; int
值。所有这些都取决于JIT编译器执行的优化深度。最后,请注意in a related question,衡量的是new Integer(1)
实际生成的更快代码而不是Integer.valueOf(1)
(问题是关于Character
,但除此之外的故事完全相同)。