Java:何时取消引用变量
希望获得一些Java遵循的幕后内存引用和规则 下面是一段代码。 基本上,该类用于实例化其他对象(MyOtherObject),然后将对该对象doClose()方法的引用发送到向量 如果创建了3个MyOtherObject对象,则向量将有3个条目 最终将调用一个进程,使侦听器遍历MyOtherObject对象的向量,并为每个对象调用doClose() 目前代码显示Java:何时取消引用变量,java,memory,dereference,Java,Memory,Dereference,希望获得一些Java遵循的幕后内存引用和规则 下面是一段代码。 基本上,该类用于实例化其他对象(MyOtherObject),然后将对该对象doClose()方法的引用发送到向量 如果创建了3个MyOtherObject对象,则向量将有3个条目 最终将调用一个进程,使侦听器遍历MyOtherObject对象的向量,并为每个对象调用doClose() 目前代码显示 myOtherObject = new myOtherObject(); 作为活动线。使用此线时,3个MyOtherObject对
myOtherObject = new myOtherObject();
作为活动线。使用此线时,3个MyOtherObject对象中只有1个将实际闭合
如果代码更改为
MyOtherObject myOtherObject = new MyOtherObject();
然后,3个MyOtherObject对象中的每一个都将调用它们的doClose()例程
public class MyObject
{
MyOtherObject myOtherObject ;
public static MyObject getInstance()
{
:
:
:
return instance;
}
public void runThis ()
{
///MyOtherObject myOtherObject = new MyOtherObject(); //Works
myOtherObject = new myOtherObject(); //Only closes one
MyCustomObjectTracker customObjectTracker = new MyCustomObjectTracker()
{
@Override
public void closingMyWindows()
{
myOtherObject.doClose();
}
};
refernceToSomeOtherObject.addMyObjectTracker(customObjectTracker);
}
}
由于“working”中的变量是本地变量,以后将无法引用,Java是否会在变量超出范围时用实际的对象引用替换该变量
在“不工作”场景中,只有1被关闭,这是因为变量是一个实例变量,并且当引用doClose()对象时,它使用执行doClose()时myOtherObject变量中的引用吗
基本上是寻找这些对象在幕后被取消引用的内容/时间,以及是否有正式的行为术语 我认为,你的困惑不是关于取消引用。我认为你的困惑在于闭包。当您创建一个匿名类实例时,您正在创建一个闭包,它执行一些神奇的调用堆栈来获取局部变量的当前状态。让我们先看看您的工作示例。(我删除了一些对此解释不必要的部分) 当您执行
newmyCustomObjectTracker(){…}
时,Java编译器会看到您使用了变量myOtherObject
,因此它会隐式关闭该变量,以便以后记住它。请注意,这里重要的一点是,每次调用runThis
,您都在生成一个新的局部变量。它可能与旧的名称相同,但您创建了一个新的局部变量。因此,每个customObjectTracker
都可以访问不同的局部变量。因此,一切都会成功。现在,让我们来看另一个例子
public class MyObject {
MyOtherObject myOtherObject;
public void runThis() {
myOtherObject = new MyOtherObject();
MyCustomObjectTracker customObjectTracker = new MyCustomObjectTracker() {
@Override
public void closingMyWindows() {
myOtherObject.doClose();
}
};
}
}
在这里,代码使用了相同的原理。我们需要关闭一个叫做myOtherObject
的东西。但是myOtherObject
不是局部变量;它是一个实例变量。所以实际上,我们需要靠近它所属的对象,即this
。请注意,此只有一个。您可以多次调用runThis
;你只在一个对象上调用它。在本例中,您将一个变量更改几次,然后创建几个新类,所有这些类都指向这一个变量
匿名类相对容易手工分解为“真实”类。因此,如果闭包让您感到困惑,请尝试将每个代码段转换为不使用匿名类的形式(因此,不要使用新建MyCustomObjectTracker(){…}
,而是使用类MySpecialCustomObjectTracker扩展MyCustomObjectTracker
创建一个新文件)。这样做会让您考虑必须向新对象传递什么状态,这是编译器在创建匿名类实例时自动执行的操作。谢谢。上课有帮助。“结束”这个术语也是我想要的。在此基础上,我搜索了“closure”并发现了以下内容:“closure是一个匿名函数,在其周围的作用域上“closure”。因此,当执行closure定义的函数时,它可以访问创建时作用域中的所有局部变量。”
public class MyObject {
MyOtherObject myOtherObject;
public void runThis() {
myOtherObject = new MyOtherObject();
MyCustomObjectTracker customObjectTracker = new MyCustomObjectTracker() {
@Override
public void closingMyWindows() {
myOtherObject.doClose();
}
};
}
}