Java 如何在类内将实例设置为null?

Java 如何在类内将实例设置为null?,java,null,garbage-collection,Java,Null,Garbage Collection,我想在我的类中创建一个发布方法。 调用release之后,如何将该实例设置为null 我的意思是: ABC abc = new ABC(); abc.release(); if(abc == null) Log.d("That's what I want"); 然后我想检查abc是否为空。 如何执行此操作?您不必从实例内部执行此操作。如果删除对该对象的所有引用,则垃圾回收器下次执行循环时将自动删除该引用 干脆 ABC abc = new ABC(); // Create new instanc

我想在我的类中创建一个发布方法。 调用release之后,如何将该实例设置为null

我的意思是:

ABC abc = new ABC();
abc.release();
if(abc == null) Log.d("That's what I want");
然后我想检查abc是否为空。
如何执行此操作?

您不必从实例内部执行此操作。如果删除对该对象的所有引用,则垃圾回收器下次执行循环时将自动删除该引用

干脆

ABC abc = new ABC(); // Create new instance and reference it with variable abc
abc = null; // remove the reference from abc; the instance is now floating around in space

您可以尝试使用显式调用垃圾收集器。我记得读到的最后一篇文章是,这仅仅表明您想要一个GC,而不是一个实际的力量,但文档只是说它“运行垃圾收集器”。

您不必从实例内部按顺序执行此操作。如果删除对该对象的所有引用,则垃圾回收器下次执行循环时将自动删除该引用

干脆

ABC abc = new ABC(); // Create new instance and reference it with variable abc
abc = null; // remove the reference from abc; the instance is now floating around in space

您可以尝试使用显式调用垃圾收集器。我记得读到的最后一篇文章是,这仅仅表明您想要一个GC,而不是一个实际的力量,但文档只是说它“运行垃圾收集器”。

此时abc不能为空。因为这个=null;不是有效的语句


您必须显式地使其为空。

此时abc不能为空。因为这个=null;不是有效的语句

您必须显式地设置为null。

变量abc是一个单向引用。可以有任意多个对对象的引用。对象无法*知道指向它的引用

您可以执行类似于请求的操作的唯一方法是,如果要使其为空的对象具有对另一个对象的引用,该对象持有对该对象的引用以使其自身为空

现在,您可以将对对象本身的这一引用设置为null。但这不会影响任何其他引用,因此该对象可能仍然被使用,并且不符合垃圾收集的条件

正如您所看到的,这个循环引用并没有揭示对象的责任和依赖关系。一般来说,应该避免循环依赖;应首选树状结构。因此,对象本身不应触发释放方法。相反,对象应更改其状态,可能更改为无效或终止状态,并通知其他感兴趣的对象,例如通过事件侦听器或总线或消息传递系统。然后,持有引用的对象必须做出反应,并将引用自身设置为null

使用正常的语言功能和模式 变量abc是一个单向引用。可以有任意多个对对象的引用。对象无法*知道指向它的引用

您可以执行类似于请求的操作的唯一方法是,如果要使其为空的对象具有对另一个对象的引用,该对象持有对该对象的引用以使其自身为空

现在,您可以将对对象本身的这一引用设置为null。但这不会影响任何其他引用,因此该对象可能仍然被使用,并且不符合垃圾收集的条件

正如您所看到的,这个循环引用并没有揭示对象的责任和依赖关系。一般来说,应该避免循环依赖;应首选树状结构。因此,对象本身不应触发释放方法。相反,对象应更改其状态,可能更改为无效或终止状态,并通知其他感兴趣的对象,例如通过事件侦听器或总线或消息传递系统。然后,持有引用的对象必须做出反应,并将引用自身设置为null

使用正常的语言功能和模式 你不能

在Java中,对对象的引用是通过值传递的。您不能有更改调用对象的引用指向的位置的方法

但您可以做的是向类ABC添加一个公共布尔isReleased方法,并将ifabc==null替换为if ABC.isReleased

任何在对象被释放后不再工作的方法在调用release后被调用时都应该抛出一个自定义异常。这比所有对对象的引用都为空时得到的NullPointerException可调试性要好得多。

你不能

在Java中,对对象的引用是通过值传递的。您不能有更改调用对象的引用指向的位置的方法

但您可以做的是向类ABC添加一个公共布尔isReleased方法,并将ifabc==null替换为if ABC.isReleased

任何在对象被释放后不再工作的方法在调用release后被调用时都应该抛出一个自定义异常。这将比当所有引用都指向obj时得到的NullPointerException具有更好的可调试性
ect将改为空。

您不能这样做。对ABC类的引用存在于调用方的类本身之外,因此ABC实例无法修改引用


您必须在ABC中实现某种状态,就像数据库连接对象那样。关闭数据库连接时,仍然有对连接对象的引用,但该对象处于关闭状态,除非先重新打开连接,否则无法再使用该对象。

您不能这样做。对ABC类的引用存在于调用方的类本身之外,因此ABC实例无法修改引用


您必须在ABC中实现某种状态,就像数据库连接对象那样。关闭数据库连接时,仍然有对连接对象的引用,但该对象处于关闭状态,除非首先重新打开连接,否则无法再使用该对象。

这取决于您何时考虑取消引用

如果您有一个对象链A->B->C,那么一旦A不可访问,A、B和C都将有资格进行垃圾收集,假设没有其他对象引用B或C。例如,没有必要,也从来没有任何必要,显式地将引用A->B或B->C设置为null

除此之外,大多数情况下,这个问题并没有真正出现,因为实际上您正在处理集合中的对象。通常,您应该始终考虑通过调用appropiate remove方法从列表、映射等中删除对象

过去有一些将引用设置为null的建议,特别是在一个很长的作用域中,内存密集型对象在作用域的一部分停止使用。例如:

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}

这里的基本原理是,由于obj仍然在范围内,因此如果没有显式地将引用置零,它在doSomethingElse方法完成之前不会成为垃圾回收。这一建议在现代JVM上可能不再适用:事实证明,JIT编译器可以计算出给定的本地对象引用在什么时候不再使用。

这取决于您何时考虑将引用置零

如果您有一个对象链A->B->C,那么一旦A不可访问,A、B和C都将有资格进行垃圾收集,假设没有其他对象引用B或C。例如,没有必要,也从来没有任何必要,显式地将引用A->B或B->C设置为null

除此之外,大多数情况下,这个问题并没有真正出现,因为实际上您正在处理集合中的对象。通常,您应该始终考虑通过调用appropiate remove方法从列表、映射等中删除对象

过去有一些将引用设置为null的建议,特别是在一个很长的作用域中,内存密集型对象在作用域的一部分停止使用。例如:

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}
这里的基本原理是,由于obj仍然在范围内,因此如果没有显式地将引用置零,它在doSomethingElse方法完成之前不会成为垃圾回收。这一建议在现代JVM上可能不再适用:事实证明,JIT编译器可以计算出给定的本地对象引用在什么时候不再使用。

不幸的是,这并不容易。 您需要这样的版本以防止进一步使用。分配null将给API客户带来负担/善意。你希望它是代码。可能间接地是:

class ABC {
    void release() { ... }
    void generateOutputOnce() {
        ...; release();
    }
}
因此,将委托关系用于实际ABC对象:

class ABC { // Maybe extends OriginalABC
     OriginalABC abc;
     ABC() {
         abc = new OriginalABC();
     }
     public void release() {
         abc = null;
     }
     public void generateOutputOnce() {
         checkRelease();
         abc.generateOutputOnce();
     }
     public void anyFunc() {
         checkRelease();
         abc.anyFunc();
     }
     private void checkRelease() {
         if (abc == null) throw new IllegalStateException("Already released");
     }
}
ABC有一个接口会有帮助;IDE也可以为代理生成存根。

不幸的是,这并不容易。 您需要这样的版本以防止进一步使用。分配null将给API客户带来负担/善意。你希望它是代码。可能间接地是:

class ABC {
    void release() { ... }
    void generateOutputOnce() {
        ...; release();
    }
}
因此,将委托关系用于实际ABC对象:

class ABC { // Maybe extends OriginalABC
     OriginalABC abc;
     ABC() {
         abc = new OriginalABC();
     }
     public void release() {
         abc = null;
     }
     public void generateOutputOnce() {
         checkRelease();
         abc.generateOutputOnce();
     }
     public void anyFunc() {
         checkRelease();
         abc.anyFunc();
     }
     private void checkRelease() {
         if (abc == null) throw new IllegalStateException("Already released");
     }
}

ABC有一个接口会有帮助;IDE也可以为代理生成存根。

abc=null;否则我就不明白了。abc=null;,怎么样;?这与池有任何关联吗?我想你是NullPointerException的粉丝……abc=null;否则我就不明白了。abc=null;,怎么样;?这与池有什么关联吗?我想你是NullPointerException的粉丝。。。