假设:
1. public class GC {
2. private Object o;
3. private void doSomethingElse(Object obj) { o = obj; }
4. public void doSomething() {
5. Object o = new Object();
6. doSomethingElse(o);
7. o = new Object();
8. doSomethingElse(null);
9. o=null;
10. }
11. }
当的doSomething
方法被调用,此后线并在Object
在第5行中创建变得可用于垃圾收集?
一个。 5号线
B.线6
C.线7
D. 8号线
E. 9号线
F.第10行
答案是D,解释是当第7行新的Object()不会新建一个新对象时,它只是第5行创建的对象。
我对此非常困惑,任何人都可以帮助我吗?
答案 0 :(得分:1)
让我们更清楚地写一下这个名字并稍微澄清一下:
public class GC {
private Object o;
private void setObj(Object obj) { o = obj; }
public void doSomething() {
Object o = new Object(); //4
setObj(o);
o = new Object(); //6
setObj(null); //7
o=null;
}
}
现在,想想第4行创建的对象需要多长时间才能生存: 在第5行,您将在封闭类中保存对它的引用。所以现在只要封闭类存在并且持有对它的引用,引用就不能用于GC。
在第7行调用setObj(null)后,封闭类不再保存对第4行中创建的对象的引用。唯一的o现有副本将是范围内的副本,但变量“o”no更长的是指那个初始对象,因为你已经覆盖了第6行的引用。
顺便说一句<你的例子有点难以阅读 - 一些格式化会使这更容易。
答案 1 :(得分:0)
第5行将o设置为new Object()
。第7行将o设置为new Object()
。每个new Object()
都是一个新对象。因此,当第7行执行时,它会构造一个新对象并将其分配给o
。 o
的先前值(它是对第5行中创建的对象的引用)不再存在。因此,对象的唯一引用消失了,因此该对象有资格进行车库收集。
答案 2 :(得分:0)
答案是after line 8
,因为类字段o
持有对line 5
在doSomethingElse
中,您要在类字段o
中存储对第5行o
的引用,因此在line 8
上无效之前,它将无法用于GC
答案 3 :(得分:0)
这很容易。仔细阅读。
第1行:创建类GC
第2行:创建Object类的引用(o)并且它没有初始化,因此它将被隐式构造函数初始化为null。
第3行:doSomethingElse(Object obj)方法接受任何对象并引用' o'在第2行中创建。它表示obj和o将引用相同的对象
第4行:功能开始
第5行:使用引用' o创建的新本地对象
第6行:我们将在第5行创建的对象传递到第3行的功能,该第3行将引用第2行的对象。这意味着“' o'第2行和第5行引用第5行创建的同一对象
第7行:第5行的本地引用现在引用新的Object但旧的对象无法进行垃圾收集,因为第2行仍在引用旧对象。
第8行:我们传递null,最终将传递给第2行,因此第2行现在将引用null而不是旧对象(在第5行创建),所以现在它可以被垃圾收集。这就是答案。
在第7行创建的第9行:对象可以进行垃圾回收,或者即使我们没有写第9行,因为函数在第10行结束,本地对象将自动符合垃圾回收的条件。
这有意义吗?
答案 4 :(得分:0)
是的,D是正确的。
在第5行,您宣布一个新的参考o
阴影类级参考o
。阴影意味着在此方法中使用o
将引用您在第5行创建的o
引用,而不是在第2行创建的引用。
因此,您在第5行创建的对象最初仅由第5行创建的o
引用引用。在第6行调用doSomethingElse
时,您传入您创建的实例在第5行,它将保存在班级o
。所以现在有两个地方知道对象;第2行的o
和第5行的o
。
在第7行,您可以删除其中一个。方法的o
现在引用一个新对象。但是,有人仍然知道在第5行创建的对象;这是在第2行创建的o
引用。
在第8行,删除最后一个引用。您将第2行定义的o
更改为null
。现在因为没有人知道该对象,它可以被垃圾收集。
如果我们不使用阴影,这里有一个更好的例子:
1. public class GC {
2. private Object a;
3. private void doSomethingElse(Object x) { a = x; }
4. public void doSomething() {
5. Object b = new Object();
6. doSomethingElse(b);
7. b = new Object();
8. doSomethingElse(null);
9. b = null;
10. }
11. }
这使它更清晰,功能相同。