当引用它们时,对象是否被清除?

lil*_*ili 2 java

public class App1 
{

 public static void main(String[] args) 
 {
   Point point_1 = new Point(5,5);
   Point point_2 = new Point(7,8);
   Circle circle_1 = new Circle(point_2, 10);
   point_1 = null;
   point_2 = null;
 }
}
Run Code Online (Sandbox Code Playgroud)

执行此代码后存在多少个对象引用?为什么?

pax*_*blo 7

此代码执行后,完全没有,因为它将退出:-)

如果你的意思是在退出之前的那一点,假设构造函数存储它,那么在你的圆圈上有一个参考,你的圆圈中有一个参考到第二个点.


pol*_*nts 7

尽管存在配方问题,但该片段在垃圾收集的某些方面实际上非常有启发性.让我们逐行看一下.

 Point point_1 = new Point(5,5);
Run Code Online (Sandbox Code Playgroud)

所以我们已经声明了一个引用变量point_1,它指向一个new Point.我们现在假设构造函数Point没有做任何奇特的事情,只是final int x, y用给定的值设置字段.

因此,我们现在有这样的事情:

现在让我们来看看下一行:

Point point_2 = new Point(7,8);
Run Code Online (Sandbox Code Playgroud)

现在我们有这样的事情:

现在让我们来看看下一行:

Circle circle_1 = new Circle(point_2, 10);
Run Code Online (Sandbox Code Playgroud)

这里我们还不太清楚如何Circle实现,但是假设它有一个final Point centerfinal int radius字段是合理的,Point center具体来说,它只是设置对给定的引用Point(即没有防御性复制,因为它Point是不可变的).

所以现在我们可能有这样的事情:

然后使用接下来的两个语句,我们分别设置point_1point_2指向null:

point_1 = null;
point_2 = null;
Run Code Online (Sandbox Code Playgroud)

所以现在我们有这样的事情:

我们现在可以观察到:

  • 该对象[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项:消除过时的对象引用

相关问题

  • 嘿,那很酷.你用什么来做那些图表? (3认同)

Ste*_*n C 5

答案是:

  1. 定义您对"存在"的对象引用的含义.
  2. 如果没有PointCircle类的详细信息,就不可能知道甚至创建了多少个对象引用.
  3. 答案是无关紧要的,因为在main方法退出后,没有任何对象可以到达......引用是否仍然"存在".

我们可以推断,在main方法返回之前的那个时间点,将有一个Circle对象的可达引用和一个可达的引用Point.但是必须对这两个类如何实现以进行推断做出一些(合理的)假设.(例如,必须假设各个构造函数不添加PointCircle引用某些静态数据结构.)

当引用它们时,对象是否被清除?

否.垃圾收集器运行时清除对象,并确定无法再访问相关对象.从这个意义上说,"可达"意味着你可以通过跟随对象的一系列引用来到达对象,从以下开始:

  • 某个类的静态属性
  • 某个线程当前正在执行的某个方法的局部变量
  • 某个其他可到达对象的属性,或
  • 一些其他可到达数组的元素.

(我已经简化了GC和可达性的解释,以避免将OP与他/她还不会理解的东西混淆.)