赋值与拷贝

Assignment | 赋值与拷贝

Pass-By-Value | 按值传递

注意,Java 中总是 Pass-By-Value,虽然很多时候它传递的是引用值,譬如下面这个例子:

public class PassByValue {

  public void modifyArrayList(ArrayList arrayList, ArrayList arrayList2) {
    arrayList.add(2);
    arrayList2 = new ArrayList();
    arrayList2.add(2);
  }

  @Test
  public void test_modifyArrayList() {
    final ArrayList arrayList = new ArrayList();
    final ArrayList arrayList2 = new ArrayList();
    arrayList.add(1);
    arrayList2.add(2);
    modifyArrayList(arrayList, arrayList2);
    System.out.println(arrayList);
    System.out.println(arrayList2);
  //[1, 2]
  //[2]
  }
}

在将 ArrayList 的引用传递到函数中时,其是对引用值做了一个复制然后新生成了一个对象,所以在函数内部可以对该对象重新指向新的 ArrayList。再看一个较为复杂的例子:

public static void main(String[] args){
    Dog aDog = new Dog("Max");
    foo(aDog);

    if (aDog.getName().equals("Max")) { //true
        System.out.println("Java passes by value.");

    } else if (aDog.getName().equals("Fifi")) {
        System.out.println("Java passes by reference.");
    }
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true

    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

在这个例子中,aDog.getName()一直返回的是MaxaDog的值并没有被foo函数中所复写。

复合类型的复制 | Copy Composite Data Types

首先来看看浅拷贝和深拷贝的定义:

  • 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。

  • 深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝

也就是说浅拷贝只复制一个对象,传递引用,不能复制实例。而深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例。对于浅拷贝当对象的成员变量是基本数据类型时,两个对象的成员变量已有存储空间,赋值运算传递值,所以浅拷贝能够复制实例。但是当对象的成员变量是引用数据类型时,就不能实现对象的复制了。

上一页