面试题:符合垃圾回收条件的对象
给出以下代码:
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
之前有多少对象可以进行垃圾回收.
The question is how many objects are eligible for garbage collection right before // Some other code
.
那么正确答案是(至少那是面试官的答案): 2 - 布尔值 b
因为它是一个包装器和 a1
.
Then correct answer is (at least that's the interviewer answer): 2 - the Boolean b
because it's a wrapper and a1
.
你能解释一下为什么 a2
和 a3
没有被垃圾收集吗?
Can you please me explain me why a2
and a3
aren't being garbage collected ?
稍后
- 好的,我想我现在明白了.一开始有点困惑,但现在我确定面试官错了.我最初的错误是,一开始我并没有考虑到 Java 只是按值传递,所以不可能从以a2"作为参数的函数内部使 a2 为空,因为 a2 实际上是 a2 的副本.
- 带有布尔b的部分确实很明显.
感谢您的回答,之后我会发送一些面试反馈:).
Thanks for an answer, I will send some interview feedback after that :).
推荐答案
假设 go
应该是 easyMethod
它是这样工作的
Assuming go
is supposed to be easyMethod
it works like this
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
.
Two objects are eligible for garbage collection (a1 and a3). b
is not because it's only a reference to null. No Boolean
was ever made.
为了解决 //Some other code
可能是什么的愚蠢微妙之处,我将问题改写为以下内容:
To get around the inane subtleties of what // Some other code
might be, I instead posit the question be reworded into the following:
预测并解释以下输出:
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:filesj>javac A.java
c:filesj>java A
null
2
null
后续的是,此时,a1 和 a3 符合 GC 条件,而 a2 则没有.
And the followup is that at that point, a1 and a3 were eligible for GC, and a2 was not.
这个问题的教训是将对象引用传递给方法并将该引用设置为 null 不会导致原始引用为 null".这就是面试官试图测试的知识.
The lesson from this question is that "Passing an object reference to a method and setting that reference to null does not cause the original reference to be nulled". That's the piece of knowledge the interviewer was attempting to test.
相关文章