Java 为什么包装器对象有资格进行垃圾收集?

Java 为什么包装器对象有资格进行垃圾收集?,java,Java,这个问题来自SCJP。我们需要找到符合垃圾收集条件的对象。答案是c3和短篇小说。我需要知道,为什么它的短篇小说符合GC的条件。这实际上是一个实例变量。这是否意味着,如果我不使用实例变量,它们就有资格进行垃圾收集 根据这本书的实际答案是:只有一个纸板对象(c1)是合格的,但它有一个关联的短包装器对象也是合格的。所以“两个”对象是合格的 class CardBoard { Short story = 200; CardBoard go(CardBoard cb) { cb

这个问题来自SCJP。我们需要找到符合垃圾收集条件的对象。答案是c3和短篇小说。我需要知道,为什么它的短篇小说符合GC的条件。这实际上是一个实例变量。这是否意味着,如果我不使用实例变量,它们就有资格进行垃圾收集

根据这本书的实际答案是:只有一个纸板对象(c1)是合格的,但它有一个关联的短包装器对象也是合格的。所以“两个”对象是合格的

class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {
      cb = null;
      return cb;
    }
    public static void main(String[] args) {
      CardBoard c1 = new CardBoard();
      CardBoard c2 = new CardBoard();
      CardBoard c3 = c1.go(c2);
      c1 = null;
      // do Stuff
    }
}

答案不是说
c3
而是说
c1
,因此它包含了
短篇小说。这是由于线路问题

c1 = null;

在这一点上,
c1
引用的对象可以被GCed,因此它引用的任何对象都可以被GCed。

答案没有说
c3
它说的是
c1
,因此它包含了
短篇小说。这是由于线路问题

c1 = null;

此时,被
c1
引用的对象可以被GCed,因此它引用的任何对象都可以被GCed。

如果没有任何对象引用
c1
,则
短篇小说=200字段(属于
c1
实例)也有资格收集。

如果没有任何内容涉及
c1
,则
短篇小说=200
字段(属于
c1
实例)也符合收集条件。

这一切都归结为垃圾收集器认为“可访问”的内容。基本上,它从所谓的垃圾收集根开始(执行线程中的局部变量就是此类根的一个示例),并遵循对其他对象的所有引用。在通过遍历所有这些引用访问了它可以访问的所有对象之后,剩下的一些对象不再是可访问的,这意味着无论您如何努力,您都不会再使用这些对象,因此它们可以被安全地丢弃(或作为垃圾收集)

虽然
c1
引用了它的
story
对象,但无法到达其中任何一个,因此它们都是合格的

class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {
      cb = null;
      return cb;
    }
    public static void main(String[] args) {
      CardBoard c1 = new CardBoard();
      CardBoard c2 = new CardBoard();
      CardBoard c3 = c1.go(c2);
      c1 = null;
      // do Stuff
    }
}

c3
从不引用对象,本示例旨在混淆,但
go()
始终返回空引用,并且从未为
c3
创建对象实例,而且它也不会挂起
c1
c2
引用的对象(虽然后者与本例无关,因为它仍然由
c2
变量引用)。

这一切都归结为垃圾收集器认为“可到达”的内容。基本上,它从所谓的垃圾收集根开始(执行线程中的局部变量就是此类根的一个示例),并遵循对其他对象的所有引用。在通过遍历所有这些引用访问了它可以访问的所有对象之后,剩下的一些对象不再是可访问的,这意味着无论您如何努力,您都不会再次使用这些对象,因此它们可以安全地丢弃(或作为垃圾收集)

虽然
c1
引用了它的
story
对象,但无法到达其中任何一个,因此它们都是合格的

class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {
      cb = null;
      return cb;
    }
    public static void main(String[] args) {
      CardBoard c1 = new CardBoard();
      CardBoard c2 = new CardBoard();
      CardBoard c3 = c1.go(c2);
      c1 = null;
      // do Stuff
    }
}

c3
从不引用对象,本示例旨在混淆,但
go()
始终返回空引用,并且从未为
c3
创建对象实例,而且它也不会挂起
c1
c2
引用的对象(尽管后者与本例无关,因为它仍然由
c2
变量引用).

一旦装入的
硬纸板
实例被GCed,您会期望
Short
实例发生什么?是啊,我在想,如果C1被丢弃,Short会发生什么?一旦装入的
硬纸板
实例被GCed,您会期望
Short
实例发生什么?是啊,我就是这样思考如果C1被垃圾化,short会发生什么?@ElliottFrisch:c3从来都不是空的。@ElliottFrisch但没有未被引用的对象。垃圾收集发生在实例上,而不是(不再)被引用的变量上包含它们。@roe很好,你说得对。它从未被实例化过。从技术上讲,它依赖于实现-
story
可能会被缓存,在这种情况下
c1.story==c2.story
并且只有
c1
才符合条件!;-)@ElliottFrisch:c3从来都是空的。@ElliottFrisch但是没有对象变得不被引用。垃圾收集发生在实例上,而不是(不再)被引用的变量上包含它们。@roe很好,你说得对。它从来没有被实例化过。从技术上讲,它依赖于实现-
story
可以被缓存,在这种情况下
c1.story==c2.story
并且只有
c1
是合格的!;-)但是为什么它会说“关联的短包装器对象也是合格的”??这是什么意思?@user2985842;不用喊了。这意味着变量
c1
引用的对象依次引用类型为
Short
的对象(称为包装对象,因为它仅包装一个原语值,除了允许将其用作对象之外没有其他用途),尽管它被引用,但不再可访问,因此有资格进行垃圾收集。如果是“关联的”部分让你绊倒了,你需要再看一看对象和类,每个
硬纸板
对象实例(根据类定义)都有一个
对象的引用,通过字段
故事
。抱歉4r大叫…我不是这个意思…我得到了正确的答案…谢谢,但它为什么这么说“也符合条件的关联短包装对象”?这是什么意思?@user2985842;无需呼喊。这意味着变量
c1
引用的对象依次引用
Short
类型的对象(称为包装对象,因为它只包装一个原语值,除了允许使用它之外没有其他用途)