Java 显式零位
在java中,显式空值在什么情况下有用。它是否通过使对象不可访问或其他方式来帮助垃圾收集器?它被认为是一个好的实践吗?通常不需要它(当然,这可能取决于VM实现)。但是,如果您有以下情况:Java 显式零位,java,Java,在java中,显式空值在什么情况下有用。它是否通过使对象不可访问或其他方式来帮助垃圾收集器?它被认为是一个好的实践吗?通常不需要它(当然,这可能取决于VM实现)。但是,如果您有以下情况: private static final Map<String, String> foo; void foo() { Object o; // use o o = null; // don't bother doing this, it isn't going to h
private static final Map<String, String> foo;
void foo()
{
Object o;
// use o
o = null; // don't bother doing this, it isn't going to help
}
编辑(忘了提到这个):
如果你在做这项工作,你会发现你声明的90-95%的变量都是最终的。最后一个变量不能更改它所指向的对象(或者它的原语值)。在大多数情况下,当一个变量是final时,如果在方法执行时接收到不同的值,则是一个错误(bug)
如果您想在使用后将变量设置为null,那么它不能是final,这意味着您有更大的机会在代码中创建bug。在Java中,如果您有一个非常长时间运行的方法,并且对对象的唯一引用是通过局部变量,那么它会有所帮助。当您不再需要该局部变量时(但当该方法将继续运行很长时间时),将该局部变量设置为null可以帮助GC。(在C#中,这很少有用,因为GC考虑了“最后可能的使用”。这种优化可能会让Java在某个时候使用——我不知道。)
同样,如果您有一个引用对象的成员字段,并且不再需要它,那么您可以通过将该字段设置为null来帮助GC
然而,根据我的经验,做这两件事实际上很少有用,而且会使代码更加混乱。很少有方法能够长时间运行,而将变量设置为null实际上与您希望该方法实现的目标无关。在不需要的时候这样做是不好的做法,如果需要的话,首先应该看看重构是否能改善设计。(您的方法或类型可能做得太多。)
请注意,将变量设置为null是完全被动的-它不会通知垃圾收集器可以收集该对象,它只是避免垃圾收集器将该引用视为下次保存该对象(GC)时保持该对象活动的原因运行。如果在方法块关闭时将要超出作用域的对象置零,则在垃圾收集方面没有任何好处。经常会遇到不理解这一点的人,他们非常努力地将很多东西不必要地设置为null。另见J2SE。来自“有效Java”:使用它来消除过时的对象引用。否则,它可能导致内存泄漏,这可能很难调试
public Object pop(){
if(size == 0)
throw new EmptyStatckException();
Object result = elements[--size];
elements[size] = null; //Eliminate Object reference
return result;
}
我发现它非常有用的一个特殊情况是,当您有一个非常大的对象,并且希望用另一个大对象替换它时。例如,请查看以下代码:
BigObject bigObject = new BigObject();
// ...
bigObject = new BigObject(); // line 3
如果BigObject的实例太大,堆中只能有一个这样的实例,那么第3行将失败,并出现OutOfMemoryError,因为在第3行中的赋值指令完成之前,第一个实例无法释放,这显然是在第二个实例准备就绪之后
现在,如果在第3行之前将bigObject设置为null:
bigObject = null;
bigObject = new BigObject(); // line 3
在构建第二个实例的过程中,当JVM耗尽堆时,可以释放第一个实例。在一些罕见的情况下,显式空值有助于GC,其中以下所有情况都是正确的:
- 变量是对象的唯一(非弱)引用
- 您可以保证不再需要该对象
- 变量将在范围内保留较长的一段时间(例如,它是长寿命对象实例中的一个字段)
- 编译器无法证明对象已不再使用,但您可以通过对代码的高级逻辑分析来保证这一点:-)
- 空检查速度非常快,因此检查空值的条件代码通常比许多备选方案(例如调用object.equals())更有效
- 如果尝试取消引用,会立即得到NullPointerException。这很有用,因为这是一种很好的编码风格,可以帮助您捕获逻辑错误
元素[size]==null吗?@AndrewLazarus看起来很正确。想象一堆大小为1的东西。它在元素[0]
中存储了一个元素。元素缓存为结果,数组中的位置为空,导致堆栈大小为0。