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

时间:2014-01-22 12:45:34

标签: java null garbage-collection

我想在班上创建一个release()方法。 致电release()后,如何将该实例设置为null

我的意思是:

ABC abc = new ABC();
abc.release();
if(abc == null) Log.d("That's what I want");

然后我想检查abc是否null。 我该怎么做?

7 个答案:

答案 0 :(得分:4)

您不必在每个sé的实例内执行此操作。如果你删除了这个对象的引用(所有引用),那么下次垃圾收集器进行轮次时它将被自动删除。

简单地做

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

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

答案 1 :(得分:1)

不幸的是不那么容易。 您希望此类版本阻止进一步使用。分配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可以为代理生成存根。

答案 2 :(得分:0)

此时abc不能是null。因为this = null;不是有效的陈述。

你必须显式地使其为null。

答案 3 :(得分:0)

变量abc是单向引用。您可以根据需要为对象提供尽可能多的引用。对象无法知道指向它的引用。

References

您可以执行与您的请求类似的操作的唯一方法是,您要“nullify”的对象是否引用另一个对象,该对象保存对象的引用(以使其无效)。

Back reference

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

正如您所看到的,这个循环引用并未揭示对象的职责和依赖性。通常应避免循环依赖;应该首选树状结构。因此,对象本身不应触发release方法。相反,对象应该更改其状态,可能更改为invalidend of life状态,并通知其他感兴趣的对象(例如,通过事件侦听器或总线或消息传递系统)。然后,持有引用的对象必须做出反应并将引用设置为null

  • 使用“普通”语言功能和模式

答案 4 :(得分:0)

你不能。

对象的引用在Java中按值传递。你不能有一个方法来改变调用对象的引用所指向的位置。

但您可以做的是在ABC类中添加public boolean isReleased()方法,并将if(abc == null)替换为if (abc.isReleased())

在释放对象后,任何不再起作用的方法在调用release()后调用它们时应抛出自定义异常。当对象的所有引用都是NullPointerException时,这比null更好的可调试性。

答案 5 :(得分:0)

你做不到。对ABC类的引用存在于类本身之外(在调用者中),因此ABC实例无法修改引用。

你必须在ABC中实现某种状态,就像数据库连接对象一样。当您关闭数据库连接时,仍然有对连接对象的引用,但该对象处于“关闭”状态,您不能再使用它(除非您首先重新打开连接)。

答案 6 :(得分:0)

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

如果你有一个对象链A-> B-> C,那么一旦A无法到达,A,B和C都有资格进行垃圾收集(假设没有其他东西指的是B或C) 。例如,没有必要,也从来没有任何需要明确地将参考A-> B或B-> C设置为null。

除此之外,大部分时间问题都没有真正出现,因为实际上你正在处理集合中的对象。您通常应该考虑通过调用适当的remove()方法从列表,地图等中删除对象。

曾经有一些建议来设置对null的引用的情况特别是在一个很长的范围内,在该范围内,内存密集型对象不再在范围的中途使用。例如:

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

这里的基本原理是因为obj仍在范围内,因此在没有显式的引用归零的情况下,在doSomethingElse()方法完成之后它才会变为垃圾收集。这是现代JVM上可能不再适用的建议:事实证明,JIT编译器可以在不再使用给定本地对象引用的哪个点上运行。