将数组元素设置为String对象时,该元素是否引用该对象?

cme*_*ren 6 java garbage-collection

摘自Oracle的官方Java教程,请参阅此处的问题2(我的样板文件).

public static void main(String[] args) {

    String[] students = new String[10];
    String studentName = "Peter Smith";
    students[0] = studentName;
    studentName = null;

    System.out.println(students[0]);

}
Run Code Online (Sandbox Code Playgroud)

答案说,studentName由于数组students仍然引用它,因此不符合垃圾收集的条件.然而,最后一行打印"彼得史密斯",所以对我来说,students[0]引用似乎是错误的studentName.有人可以解释一下吗?

the*_*ger 7

我想一步一步地借助图解释.

String studentName = "Peter Smith";
Run Code Online (Sandbox Code Playgroud)

在第一行之后,在String池中创建一个String,并且引用名称studentName指向它.

第1部分

students[0] = studentName;
Run Code Online (Sandbox Code Playgroud)

此时,另一个参考学生[0]指向同一个对象,如下图所示.现在有2个引用指向在内存中创建的同一对象.

第2部分

studentName = null;
Run Code Online (Sandbox Code Playgroud)

在此之后,studentName的引用将指向null,即它指向没有对象.但是学生[0]的引用仍然指向String对象(Peter Smith)创建的.

在此输入图像描述

显然,在第三个语句之后,一个引用指向null,但是一个引用仍指向创建的Object.因此,该对象不符合垃圾回收的条件.

希望能帮助到你.

更新:对不起,如果我搞乱了变量名称.但我希望你明白这个主意.


Eri*_*rom 5

您将引用变量(studentNamestudents[0])与它们引用的对象("Peter Smith")混淆.studentNamestudents[0]均引用String对象"彼得·史密斯".一旦他们都没有引用"彼得史密斯" - 并假设其他地方没有其他参考 - 该对象将有资格进行垃圾收集.当它们超出范围时,引用本身就会消失.

教程弄错了.没有对象studentName.studentName是一个变量,在某一点上,持有对"彼得史密斯"的引用,在另一点上是null.类似地,students[0]是一个内存位置数组中的一个元素,它包含对"Peter Smith"(同一个String对象)的引用.该教程将变量的概念与它们引用的对象混淆.

我可能推测他们这样做是为了避免深入了解内存使用的细节.这是一个高级主题.但他们的解释IMO引起的混乱比它阻止的更多.