Java:何时取消引用变量

Java:何时取消引用变量,java,memory,dereference,Java,Memory,Dereference,希望获得一些Java遵循的幕后内存引用和规则 下面是一段代码。 基本上,该类用于实例化其他对象(MyOtherObject),然后将对该对象doClose()方法的引用发送到向量 如果创建了3个MyOtherObject对象,则向量将有3个条目 最终将调用一个进程,使侦听器遍历MyOtherObject对象的向量,并为每个对象调用doClose() 目前代码显示 myOtherObject = new myOtherObject(); 作为活动线。使用此线时,3个MyOtherObject对

希望获得一些Java遵循的幕后内存引用和规则

下面是一段代码。 基本上,该类用于实例化其他对象(MyOtherObject),然后将对该对象doClose()方法的引用发送到向量

如果创建了3个MyOtherObject对象,则向量将有3个条目

最终将调用一个进程,使侦听器遍历MyOtherObject对象的向量,并为每个对象调用doClose()

目前代码显示

 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();
            }
        };
    }
}