6

我正在准备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 及其权重将有资格进行垃圾收集。也许我错过了一些东西,请指教。

4

3 回答 3

8

让我们Icelandic()在第 11IceA行、第 12行等上调用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

所以只剩Icelandic()下第 12 行创建的。现在,每个Icelandic()都有一个Long weight, soIceA并且IceC现在没有被引用,这意味着 4 个对象 ( IceA, IceA.weight, IceC, IceC.weight) 可用于 GC。


其他问题:

  1. args仍然是args,他们没有计算超出这个问题的范围
  2. Long weight不是静态声明的,所以类的每个实例都有一个weight对象。
于 2012-11-29T21:13:52.050 回答
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”不再被引用,它们连同它们的“权重”都符合垃圾回收的条件,所以总共有四个对象。

于 2012-11-29T21:23:35.637 回答
2

您将在系统中有 4 个对象、3 个Icelandic实例和 1 个Long实例。

当您将常量对象分配给某个变量时,编译器使用一种由所有实例private static final Long long1200 = Long.valueOf(1200L);共享的对象。weight

原始类型包装器是不可变的,因此进行这种优化是安全的。

编辑:可能我错了,因为如果我们在这里多次引用相同的常量,这将起作用,但事实并非如此

于 2012-11-29T21:22:04.530 回答