class CardBoard {
Short story = 200;
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);
System.out.println("c3 value : "+c3);
c1 = null;
System.out.println("c1 value : "+c1);
System.out.println("c2 value : "+c2);
// do Stuff
}
}
这是SCJP6模拟考试的一个例子。问题是:当达到// doStuff时,有多少对象符合GC条件?答案是(2个对象)因为:只有一个CardBoard对象(c1)符合条件,但它有一个相关的Short 包装对象也符合条件。
当我执行代码时,看起来c3也指向null ...所以我会说3个对象符合GC的条件。
有人可以指导我完成此代码的逻辑。
答案 0 :(得分:10)
对象c3
原来是null,所以没有回忆它的问题,因为它从来就不存在。垃圾收集器用于清除堆上实际存在的对象。
其余的,c2
的引用永远不会丢弃,因此不会被回收。虽然在CardBoard c3 = c1.go(c2);
语句中c2似乎无效,但事实并非如此。 c2
的引用已通过值传入,虽然引用无效,但在main方法中存在对该对象的引用。因此它不会被收回。
这使我们留下c1
,它已被明确无效,因此有资格收集。但是,c1还包含对Short
变量故事的引用,该变量故事没有来自任何其他对象的任何入站引用。这导致两个对象符合清理条件 - 一个CardBoard对象和嵌入的Short对象。
答案 1 :(得分:2)
CardBoard c1 = new CardBoard();
创建CardBoard
实例及其Short
实例。 (2个对象)
将CardBoard
引用分配给c1
。
CardBoard c2 = new CardBoard();
创建另一个CardBoard
实例及其Short
实例。 (另外2个对象)
将CardBoard
引用分配给c2
。
CardBoard c3 = c1.go(c2);
将null
分配给c3
。 (go
方法是一个技巧,看你是否理解Java参数传递语义。如果你认为Java使用pass-by-reference,你可能会错误地认为c2
设置为{{1}通过这个电话。事实上,null
没有改变。)
c1 = null;
将c2
分配给null
。这将呈现第一个c1
实例及其CardBoard
实例无法访问,以及垃圾收集的候选者。
第二个Short
实例及其CardBoard
实例仍可访问。
答案 2 :(得分:1)
c3从不指向任何对象,它始终是一个空变量。因此,对象c3不符合GC
的条件答案 3 :(得分:0)
在您的代码中,只有c1和c1中包含的故事(短片)才有资格使用GC。即2个对象。
c3永远不会引用任何对象,因为go()方法返回null。
c2不适用于GC。与Java方法一样,参数按值传递。当go方法被调用时,c2一直指向对象,虽然在go方法中,传递的变量被赋值为null。