当我们将局部变量传递给异步回调时,我们必须将它们声明为final(好吧,它们至少应该是有效的final),因为java不能引用局部变量,因此它应该做一些“技巧”来将局部对象的副本传递给内部类。另一方面,成员变量在封闭对象的生存期内确实存在,因此它们可以被内部类示例引用。因此,由于内部对象可以引用外部对象的类变量,我有一个问题-这两个代码段在内存管理方面有什么区别吗
代码段1
SomeHttpLib.getData(new OnReponseHandler() {
@Override
public void onResponse(String response) {
myClassVariable.doSomething()
}
})
代码段2
SomeHttpLib.getData(new OnReponseHandler() {
@Override
public void onResponse(String response) {
MyClass.this.myClassVariable.doSomething()
}
})
这两个片段之间的唯一区别是第二个片段访问 myClassVariable
通过 this
参考,而第一个直接。因此,第一个示例似乎“捕获”了 myClassVariable
并且防止对象被释放(或者至少推迟释放),但是外部对象本身可以被释放!而第二个例子 myLocalVariable
通过 this
ref使回调捕获外部对象,从而延长其生命!那么,我的推理是正确的,还是遗漏了什么?
请不要太难判断我的问题,我只是在学习java并试图理解事情是如何发生的
谢谢您
谨致问候,
安德烈
1条答案
按热度按时间e5nszbig1#
没有区别,两个代码段编译成完全相同的东西。
因此,第一个示例似乎“捕获”了对myclassvariable的引用,并防止对象被释放(或者至少推迟释放),但是外部对象本身可以被释放!
不是这样的。
myClassVariable
如果不单独捕获,它仍将引用对象的字段(外部this
)并在回调运行时解析,因此整个对象保持活动状态。只有局部变量被单独捕获(为了使其工作,它们需要有效地被捕获)
final
,因为它们在创建回调时的值是捕获的,而不是对它们的引用)。