是什么导致java以不同的方式处理这两种对象类型的ArrayLists和Integers?

时间:2014-09-12 22:34:56

标签: java

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?




    }
}

4 个答案:

答案 0 :(得分:4)

这是因为Integer对象实际上是boxed个原语。当您致电Integer a= new Integer (5);时,您将创建一个新的整数。执行Integer b = a;时,b将相同的 Integer实例称为a。

当您致电a = a+1;时,会发生以下情况:

  1. a已取消装入原始int,其值为5。
  2. 评估向int添加一个的结果。
  3. 结果6被装入一个值为6的 new Integer。值5的原始整数不会被修改。
  4. 如果是列表,则您要分配arbr来引用java.util.ArrayList相同实例。当您通过arbr访问时,会看到对该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]

arbr是同一个实例

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)

今天早些时候刚刚问过这个问题,整数b是不变的,不会改变,但是arraylist只是一个参考...