给出以下代码:
class A {
Boolean b;
A easyMethod(A a){
a = null;
return a;
}
public static void main(String [] args){
A a1 = new A();
A a2 = new A();
A a3 = new A();
a3 = a1.easyMethod(a2);
a1 = null;
// Some other code
}
}
问题是在 //Some other code
之前有多少对象可以进行垃圾回收。
那么正确答案是(至少那是面试官的答案): 2 - boolean 值 b
因为它是一个包装器和 a1
。
你能解释一下为什么 a2
和 a3
没有被垃圾收集吗?
稍后编辑:
- 好的,我想我现在明白了。一开始有点困惑,但现在我确定面试官错了。我最初的错误是,一开始我并没有考虑到 Java 只是按值传递,所以不可能从以“a2”作为参数的函数内部使 a2 为空,因为 a2 实际上是 a2 的副本。
- 带有 boolean b的部分确实很明显。
感谢您的回答,之后我会发送一些面试反馈:)。
最佳答案
假设 go
应该是 easyMethod
它像这样工作
class A {
Boolean b;
A easyMethod(A a){
a = null; // the reference to a2 was passed in, but is set to null
// a2 is not set to null - this copy of a reference is!
return a; // null is returned
}
public static void main(String [] args){
A a1 = new A(); // 1 obj
A a2 = new A(); // 2 obj
A a3 = new A(); // 3 obj
a3 = a1.go(a2); // a3 set to null and flagged for GC - see above for why
a1 = null; // so far, a1 and a3 have been set to null and flagged
// Some other code
}
}
有两个对象可以进行垃圾回收(a1 和 a3)。 b
不是因为它只是对 null 的引用。从来没有Boolean
。
为了解决 //Some other code
可能是什么的愚蠢微妙之处,我将问题改写为以下内容:
预测并解释以下输出:
class A {
int i;
A(int i) { this.i = i; }
public String toString() { return ""+i; }
A go(A a){
a = null; // the reference to a2 was passed in, but is set to null
// a2 is not set to null - this copy of a reference is!
return a; // null is returned
}
public static void main(String [] args){
A a1 = new A(1); // 1 obj
A a2 = new A(2); // 2 obj
A a3 = new A(3); // 3 obj
a3 = a1.go(a2); // a3 set to null and flagged for GC - see above for why
a1 = null; // so far, a1 and a3 have been set to null and flagged
test(a1);
test(a2);
test(a3);
}
static void test(A a) {
try { System.out.println(a); }
catch(Exception e) { System.out.println((String)null); }
}
}
然后输出:
c:\files\j>javac A.java
c:\files\j>java A
null
2
null
后续的是,此时,a1 和 a3 符合 GC 条件,而 a2 则没有。
这个问题的教训是“将对象引用传递给方法并将该引用设置为 null 不会导致原始引用为 null”。这就是面试官试图测试的知识。
关于java - 面试题: Objects eligible for garbage collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299604/