赋值与拷贝
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()
一直返回的是Max
,aDog
的值并没有被foo
函数中所复写。
复合类型的复制 | Copy Composite Data Types
首先来看看浅拷贝和深拷贝的定义:
-
浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。
-
深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝
也就是说浅拷贝只复制一个对象,传递引用,不能复制实例。而深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例。对于浅拷贝当对象的成员变量是基本数据类型时,两个对象的成员变量已有存储空间,赋值运算传递值,所以浅拷贝能够复制实例。但是当对象的成员变量是引用数据类型时,就不能实现对象的复制了。