当我向列表中添加对象并更改对象的属性时,该更改将传播到列表中的对象,但是当我将对象设置为null时,我不会从列表中的对象获取空指针。为什么会这样?
public class Hworld {
public static void main(String[]args) {
List<Obj> list = new ArrayList<>();
Hworld.Obj o = new Obj();
list.add(o);
for(Obj ob:list) {
System.out.println(ob.b); // prints "base"
}
o.b="new";
o=null;
for(Obj ob:list) {
System.out.println(ob.b); // prints "new"
}
}
public static class Obj{
String b = "base";
}
}
答案 0 :(得分:1)
您创建一个名为o的对象。然后将其放入列表,这意味着该列表存储了对当前存储在o中的对象的引用。循环内的打印结果是基本的,因为只有一个对象,其“基本”存储在b中。
然后修改o,将o的b设置为“新”。由于o和存储在列表中的对象相同,因此o的修改也会导致存储在列表中的对象发生变化。这些是相同的对象。
然后将o设置为null。这意味着o现在指向空,而列表中存储的对象指向最初存储在o中的对象。
最初,o指向A,您将o添加到列表中,因此列表知道A,而不是o。如果随后使用o修改A,则可以使用o到A的方式以及列表到A的方式访问此更改。然后将o设置为了解B,列表仍然了解A,但不了解B,因为列表存储A,而不是B。发送者只是将有关A的知识纳入列表中。
答案 1 :(得分:1)
这是因为java使用引用。创建对象 o 时,现在在堆中创建的新对象 o 指向该位置,或者 o 引用< / strong>到新创建对象的地址。现在,您已将对象 o 添加到列表中,因此列表具有对相同位置的引用(暂时将其称为位置)。现在,您对引用 o 进行了点 。操作,该操作实际上更改了对象中成员变量的值。现在,您将引用 o 指向无处,或者只是将引用设置为 null 。但是列表中存在引用,但您尚未更改该引用。因此,您将不会获得任何NPE,并且可以使用 dot(。)运算符更早地更改值。 希望我能提供一些启示。