我想在班上创建一个release()
方法。
致电release()
后,如何将该实例设置为null
?
我的意思是:
ABC abc = new ABC();
abc.release();
if(abc == null) Log.d("That's what I want");
然后我想检查abc
是否null
。
我该怎么做?
答案 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
是单向引用。您可以根据需要为对象提供尽可能多的引用。对象无法知道指向它的引用。
您可以执行与您的请求类似的操作的唯一方法是,您要“nullify”的对象是否引用另一个对象,该对象保存对象的引用(以使其无效)。
现在,您可以将对象本身的这一个引用设置为null
。但是这不会影响任何其他引用,因此仍然可以使用该对象,并且不符合垃圾回收的条件。
正如您所看到的,这个循环引用并未揭示对象的职责和依赖性。通常应避免循环依赖;应该首选树状结构。因此,对象本身不应触发release
方法。相反,对象应该更改其状态,可能更改为invalid
或end 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编译器可以在不再使用给定本地对象引用的哪个点上运行。