Java中垃圾收集的合格变量
我正在为OCPJP做准备,我被困在以下模拟考试题目中:
鉴于:
3. interface Animal { void makeNoise(); } 4. class Horse implements Animal { 5. Long weight = 1200L; 6. public void makeNoise() { System.out.println("whinny"); } 7. } 8. public class Icelandic extends Horse { 9. public void makeNoise() { System.out.println("vinny"); } 10. public static void main(String[] args) { 11. Icelandic i1 = new Icelandic(); 12. Icelandic i2 = new Icelandic(); 12. Icelandic i3 = new Icelandic(); 13. i3 = i1; i1 = i2; i2 = null; i3 = i1; 14. } 15. }
到达第14行时,有多少对象符合垃圾收集器的条件?
A. 0
B. 1
C. 2
D. 3
E. 4
F. 6
他们的正确答案是E,即四个物体,但我不确定为什么。 从我的角度来看,i2及其重量将有资格进行垃圾收集。 也许我错过了什么,请指教。
让我们在第11行IceA
,第12行IceA
上调用Icelandic()
,依此类推。
创作之后
i1 = IceA i2 = IceB i3 = IceC
在i3 = i1
i1 = IceA i2 = IceB i3 = IceA
在i1 = i2
i1 = IceB i2 = IceB i3 = IceA
在i2 = null
i1 = IceB i2 = null i3 = IceA
在i3 = i1
i1 = IceB i2 = null i3 = IceB
所以只剩Icelandic()
12行创建的Icelandic()
。 现在,每个Icelandic()
都具有Long weight
,因此IceA
和IceC
现在IceC
被引用,这意味着4个对象( IceA
, IceA.weight
, IceC
, IceC.weight
)可用于GC。
其他问题:
-
args
仍然是args
,他们不计算这个问题超出范围 -
Long weight
不是静态声明的,因此类的每个实例都有一个weight
对象。
让我们称之为第一个创建“A”的冰岛对象,第二个称为“B”,第三个称为“C”。 在第12行之后,它们分别由i1,i2和i3引用。
现在,我们做:
i3 = i1; // object "C" is no longer referenced, object "A" is now referenced by i1 and i3 i1 = i2; // object "A" is just referenced by i3, object "B" is referenced by i1 and i2 i2 = null; // object "B" is just referenced by i1 now i3 = i1; // object "B" is referenced by i1 and i3, object "A" is no longer referenced
因此,不再引用对象“A”和“C”,它们及其“权重”符合垃圾收集条件,因此总共有四个对象。
系统中将有4个对象,3个Icelandic
实例和1个Long
实例。
当你将常量对象赋给某个变量时,编译器会使用一种private static final Long long1200 = Long.valueOf(1200L);
所有权weight
实例共享的对象。
原始类型包装器是不可变的,因此进行此优化是安全的。
编辑:可能我错了,因为如果我们在这里多次引用相同的常量,这将是这样的,但实际情况并非如此