ArrayList和Integer都是对象数据类型,但为什么下面的代码以不同的方式对待这两者? ar,br,a和b都是对象。 改变ar改变br,但改变a没有改变b为什么?不是ArrayLists和Integers都是对象吗?使用=语句将一个对象赋值给另一个对象只是将浅拷贝FOR BOTH?还是不?
import java.util.ArrayList;
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
ArrayList <Integer> ar = new ArrayList<>(Arrays.asList(1,2,3));
ArrayList<Integer> br = ar;
System.out.println(Arrays.toString(br.toArray()));// [1,2,3]
ar.remove(0);// lets change ar
// now lets see if br changed too
System.out.println(Arrays.toString(br.toArray()));// [2,3] (yes did)
Integer a= new Integer (5);
Integer b = a;
a = a+1;// lets change a and see if b changed too
System.out.println(b);// b is still 5
//So changing ar changed br too, but changing a did not change b why? Ist it both br and b are objects?
}
}
答案 0 :(得分:4)
这是因为Integer对象实际上是boxed个原语。当您致电Integer a= new Integer (5);
时,您将创建一个新的整数。执行Integer b = a;
时,b将相同的 Integer实例称为a。
当您致电a = a+1;
时,会发生以下情况:
int
,其值为5。int
添加一个的结果。Integer
。值5的原始整数不会被修改。如果是列表,则您要分配ar
和br
来引用java.util.ArrayList
的相同实例。当您通过ar
和br
访问时,会看到对该arraylist的修改。
关键点是a = a+1
通过取消装箱,评估和装箱来构建新的java.lang.Integer()
,而ar.remove(0);
会影响该列表,而不会创建新的副本。
更多JLS阅读:
如果p是int类型的值,那么装箱转换将p转换为类的引用r并输入Integer,这样
r.intValue() == p
答案 1 :(得分:1)
您需要了解变量,参考值(以及字段访问和方法调用的解除引用)和对象之间的区别。
变量只是值的持有者。
参考值是一个被解释为对象位置的值。
对象是......一个对象。它具有可访问的字段和可调用的方法。
下面
ArrayList <Integer> ar = new ArrayList<>(Arrays.asList(1,2,3));
ArrayList<Integer> br = ar;
您创建两个存储单个引用值的变量,该引用值指向使用new ArrayList<>(..)
创建的单个实例。所以这两个变量都引用了同一个对象。
使用方法调用表达式
调用方法时ar.remove(..);
JVM使用引用值来查找对象并调用其方法。这是br
引用的同一对象。所以,当你那么做
br.toArray()
你仍在访问同一个对象。
下面
Integer a = new Integer (5);
Integer b = a;
创建两个引用同一对象的变量。
然后你做
a = a+1;// lets change a and see if b changed too
为变量=
分配(a
)新的参考值。所以现在a
引用了与b
不同的对象。
答案 2 :(得分:0)
所以:
ArrayList <Integer> ar = new ArrayList<>(Arrays.asList(1,2,3));
ArrayList<Integer> br = ar;
System.out.println(Arrays.toString(br.toArray()));// [1,2,3]
ar
和br
是同一个实例
ar.remove(0);// lets change ar
// now lets see if br changed too
System.out.println(Arrays.toString(br.toArray()));// [2,3] (yes did)
ar
的内容已更改。自ar == br
起,可以在br
中看到更改。
Integer a = new Integer (5);
Integer b = a;
a
是一个新对象,b
再次被指定为同一个实例
a = a+1; // lets change a and see if b changed too
System.out.println(b); // b is still 5
a
的引用已更改。 a
现在指向新创建的对象。 b
仍然指向第一个创建的对象。
答案 3 :(得分:-3)