Java之深淺拷貝
基本類型:拷貝數(shù)據(jù)的值
其他類型:拷貝地址的引用伍伤,拷貝出的新對(duì)象與原對(duì)象共享實(shí)例變量并徘,不受訪問(wèn)權(quán)限影響
String類型:拷貝的也是一個(gè)引用,但其內(nèi)容存儲(chǔ)在字符串池中扰魂,修改時(shí)會(huì)重新生成新的字符串麦乞,原有字符串內(nèi)容是保持不變的(String是不可變的),等同于基本類型劝评。
淺拷貝
淺拷貝就是直接使用"="給基本類型賦值(即使拷貝引用)
List<String> srcList = new ArrayList<>();
srcList.add("android");
List<String> cpyList = srcList;
srcList.add("ios");
輸出這兩個(gè)list姐直,srcList和cpyList都有android,ios兩項(xiàng)蒋畜。
深拷貝
深拷貝就是將所有屬性均拷貝到另外一個(gè)對(duì)象中声畏,將其中任何一個(gè)對(duì)象的任何一個(gè)屬性發(fā)生變化時(shí),另外一個(gè)對(duì)象不受任何影響姻成。
List<String> srcList = new ArrayList<>();
srcList.add("android");
List<String> cpyList = new ArrayList<>(srcList);
srcList.add("ios");
輸出這兩個(gè)list插龄,srcList有android,ios兩項(xiàng)科展,而cpyList只有android一項(xiàng)均牢。
clone方法實(shí)現(xiàn)拷貝
每個(gè)對(duì)象都是繼承于Object類的,Object類提供了clone方法才睹,通過(guò)實(shí)現(xiàn)Cloneable接口可以使該具有拷貝的能力徘跪,拷貝的操作是在內(nèi)存中進(jìn)行中,所以性能會(huì)比直接構(gòu)造對(duì)象要快速很多琅攘。
public class Student implements Cloneable {
private String name;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
protected Student clone() {
Student s = null;
try {
s = (Student) super.clone();
s.setTeacher(s.getTeacher());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return s;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("Yao");
s1.setTeacher(new Teacher("Kobe"));
Student s2 = s1.clone();
s2.setName("Yi");
s2.getTeacher().setName("Jordan");
System.out.println(s1.getName() + "'s teacher is "
+ s1.getTeacher().getName());
System.out.println(s2.getName() + "'s teacher is "
+ s2.getTeacher().getName());
}
}
class Teacher {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher(String name) {
super();
this.name = name;
}
}
輸出:
Yao's teacher is Jordan
Yi's teacher is Jordan
這里關(guān)于teacher的拷貝是通過(guò)"="號(hào)來(lái)操作的真椿,僅僅實(shí)現(xiàn)了淺拷貝。
@Override
protected Student clone() {
Student s = null;
try {
s = (Student) super.clone();
s.setTeacher(new Teacher(s.getTeacher().getName()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return s;
}
將Student類的clone方法改成這樣即可實(shí)現(xiàn)深拷貝乎澄。
輸出:
Yao's teacher is Kobe
Yi's teacher is Jordan
通過(guò)對(duì)象序列化,使用writeObject和readObject也可以實(shí)現(xiàn)對(duì)象的深拷貝测摔。