我试图理解这个问题,但无法通过书中提供的答案得到解决。有人可以向我解释一下吗?问题如下。
class CardBoard {
Short story = 5;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// do stuff
}
}
当//达到了什么东西时,有多少对象可以进行垃圾回收?
答案是 2个对象。只有一个CardBoard对象(c1)符合条件,但它有一个相关的Short包装器对象,也符合条件
我不明白为什么单独的对象c1有资格进行垃圾回收。
创建了两个对象,c1和c2。
对于对象c3,我们将c2传递给c1.go()方法。并且将其设置为null并将返回的对象赋予c3。
在方法c1.go()中,cb reffering(通过我的承诺,与c2相同的对象)被设置为null的对象。那不会使c2 reffering的对象也可用于垃圾收集吗?
答案 0 :(得分:0)
Java是按值传递。当您执行CardBoard c3 = c1.go(c2);
时,c2
指向的实例会传递到go()
,但是当您执行cb=null
时,原始c2's cb
未设置为{ {1}},新的空引用null
被压入堆栈并返回。因此,只有2个对象(aconst_null
和Short
)符合GC条件。
PS:正如Andreas所说,{ - 1}}值被缓存在-128到127之间的值,因此在您的情况下,将重用相同的c1
实例。因此,只有一个对象符合GC条件。如果您的Short
值超出该范围,则2个对象将有资格使用GC。
答案 1 :(得分:0)
Java是按值传递的,因此当您将参数cb
置空时,这不会更改变量c2
的值。
go()
方法调用最终会返回null
,保持c1
和c2
不变。
因此,当执行到// do stuff
时,c1
为空,c2
引用第二个对象,c3
为空。这意味着第一个对象符合GC的条件。
由于每个对象都有一个Short
引用,因此您认为将释放两个对象(第一个对象及其story
),并且将保留两个对象(第二个对象及其{ {1}}),但事实并非如此。
story
值为5将不会创建Short
对象的新实例。 -128和127之间的值(包括)缓存,缓存值是永久值。
这意味着真正的答案是只分配了2个对象,并且第一个对象符合GC的条件。 Short
引用不会分配任何内容。