尽管存在公式化问题,但 sn-p 实际上对垃圾可收集性的某些方面很有指导意义。让我们逐行看一下。
Point point_1 = new Point(5,5);
所以我们声明了一个引用变量point_1,它指向一个new Point。现在让我们假设Point 的构造函数没有做任何花哨的事情,而是简单地使用给定值设置字段final int x, y。
因此,我们现在有这样的东西:
现在让我们看看下一行:
Point point_2 = new Point(7,8);
现在我们有这样的东西:
现在让我们看看下一行:
Circle circle_1 = new Circle(point_2, 10);
这里我们也不太清楚Circle 是如何实现的,但可以合理地假设它有final Point center 和final int radius 字段,特别是Point center,它只是将引用设置为给定的Point(即没有防御性复制,因为Point 是不可变的)。
所以现在我们可能有这样的东西:
然后在接下来的两个语句中,我们将point_1 和point_2 分别设置为指向null:
point_1 = null;
point_2 = null;
所以现在我们有这样的东西:
我们现在可以观察到:
- 对象
[aPoint(5 5)] 不再可访问
-
[aPoint(7 8)] 对象虽然不再被 point_2 引用,但仍被 [aCircle(10)].center 引用。
垃圾回收性是由一个对象是否可以被实时引用访问定义的。我们可以强烈假设对象[aPoint(5 5)](基于我们认为Point 的实现方式)不再可访问,因此它有资格被收集(它是垃圾!现在没有人可以“捡起它”!) .
另一方面,对象[aPoint(7, 8)] 仍然被[aCircle(10)].center 引用,所以我们可以说它不符合收集条件(它不是垃圾!有人还在“挂上”!)。
道德
所以不,绝对设置对null 的引用确实不会 使先前被引用的对象自动符合收集条件。这取决于对象本身,是否存在对该对象的任何引用。
当然,设置对 null 的引用 CAN 有助于使对象符合收集条件,例如当该引用是对象的最后一个剩余时。
不但是,您必须始终设置对null 的引用以使垃圾收集“有效”。当变量超出范围时,引用不再有效,因此在这种情况下,显式设置为 null 只是多余的代码。
显式设置为null DOES 的经典示例是Stack 示例:当顶部元素从Stack 弹出时,Stack 不应再引用对象来自其内部数据结构。
另见
- 有效的 Java 第 2 版,第 6 条:消除过时的对象引用
相关问题