【发布时间】:2021-06-08 07:32:49
【问题描述】:
我以为我知道这个问题的答案,但经过一个小时左右的搜索,我找不到任何确认。
在这段代码中:
public class Outer {
// other code
private void method1() {
final SomeObject obj1 = new SomeObject(...);
final SomeObject obj2 = new SomeObject(...);
someManager.registerCallback(new SomeCallbackClass() {
@Override
public void onEvent() {
System.out.println(obj1.getName());
}
});
}
}
假设registerCallback 将它的参数保存在某个地方,这样匿名子类的对象就会存活一段时间。显然,这个对象必须保持对obj1 的引用,这样onEvent 才能在被调用时工作。
但是考虑到该对象不使用obj2,它是否仍然保持对obj2 的引用,以便obj2 在对象存在时不能被垃圾回收?我的印象是all可见final(或实际上是最终的)局部变量和参数被捕获,因此只要对象还活着就不能被GC'ed,但我可以'找不到任何说法。
它是否依赖于实现?
JLS 中有一个部分可以回答这个问题吗?我无法在那里找到答案。
【问题讨论】:
-
你怎么知道
obj2绑定到callback$x?你在字节码中见过吗? -
"是否依赖于实现?"从技术上讲,是的。匿名类没有理由捕获
obj2,但没有理由不能。 -
我认为它不会捕获
obj2的一个很好的理由当然是你可以在一个方法中声明多个匿名类:其中一个类可能只引用obj1,而另一个可能只提到obj2。两个类都捕获这两个变量是不明智的。 -
您可以使用反射或调试器进行检查。
标签: java anonymous-class