我正准备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行时,有多少对象符合垃圾收集器的条件?
一个。 0
B中。 1
℃。 2
d。 3
电子。 4
F。 6
他们的正确答案是E,即四个物体,但我不知道为什么。从我的角度来看,i2及其重量将有资格进行垃圾收集。也许我错过了什么,请指教。
答案 0 :(得分:8)
让我们在第11行Icelandic()
,第12行IceA
等处致电IceB
,等等。
创建后
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
因此只剩下第12行创建的Icelandic()
。现在,每个Icelandic()
都有Long weight
,因此IceA
和IceC
现在未被引用,意味着4个对象(IceA
,IceA.weight
,{{ 1}},IceC
)可用于GC。
IceC.weight
仍为args
,他们不计算超出此问题的范围args
未静态声明,因此该类的每个实例都有一个Long weight
对象。答案 1 :(得分:3)
让我们调用第一个创建“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”,它们及其“权重”符合垃圾收集条件,因此共有四个对象。
答案 2 :(得分:2)
系统中将有4个对象,3个Icelandic
个实例和1个Long
个实例。
当您将常量对象分配给某个变量时,编译器会使用所有private static final Long long1200 = Long.valueOf(1200L);
个实例共享的weight
对象。
原始类型包装器是不可变的,因此可以安全地进行此优化。
编辑:可能我错了,因为如果我们在这里多次引用相同的常量,这将是这样的,事实并非如此