在Java中,對于對象的拷貝有兩種方式,一種是深拷貝,另一種是淺拷貝。
淺拷貝只是創(chuàng)建一個新的對象,并將原對象的引用傳遞給新對象,因此新對象和原對象共享相同的內(nèi)存地址。而深拷貝則是創(chuàng)建一個新對象,并將原對象中的所有基本數(shù)據(jù)類型和非基本數(shù)據(jù)類型都復(fù)制到新對象中,新對象和原對象完全獨立。
// 淺拷貝示例 public class User implements Cloneable { private String name; private Listhobbies; // 省略setter和getter方法 @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } User user1 = new User(); user1.setName("張三"); List hobbies = new ArrayList<>(); hobbies.add("游泳"); hobbies.add("跑步"); user1.setHobbies(hobbies); User user2 = (User) user1.clone(); System.out.println(user1 == user2); // false System.out.println(user1.getHobbies() == user2.getHobbies()); // true,引用相同
// 深拷貝示例 public class User implements Serializable { private String name; private Listhobbies; // 省略setter和getter方法 public User deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (User) ois.readObject(); } } User user1 = new User(); user1.setName("張三"); List hobbies = new ArrayList<>(); hobbies.add("游泳"); hobbies.add("跑步"); user1.setHobbies(hobbies); User user2 = user1.deepClone(); System.out.println(user1 == user2); // false System.out.println(user1.getHobbies() == user2.getHobbies()); // false,引用不同
從示例中可以看出,在進行淺拷貝時,新對象和原對象的引用存在相同的情況,因此對于引用類型的屬性,在改變新對象的屬性值時,原對象的屬性值也會一并改變。而在深拷貝中,則可以完全避免這種情況。