public class Interesting { public static void main(String[] args) throws CloneNotSupportedException { User original = new User(); original.setUserId(1); original.setUserName("original"); List<Integer> scoreList = new ArrayList<>(); scoreList.add(11); scoreList.add(111); scoreList.add(1111); original.setScoreList(scoreList); User clone2 = (User) original.clone(); clone2.setUserId(2); clone2.setUserName("clone1"); clone2.setScoreList(Arrays.asList(22, 222, 2222)); User clone3 = (User) original.clone(); clone3.setUserId(3); clone3.setUserName("clone3"); clone3.getScoreList().add(333); User clone4 = (User) clone2.clone(); clone4.setUserId(4); clone4.setUserName("clone4"); clone4.getScoreList().add(444);//UnsupportedOperationException } static class User implements Cloneable{ private int userId; private String userName; private List<Integer> scoreList; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public List<Integer> getScoreList() { return scoreList; } public void setScoreList(List<Integer> scoreList) { this.scoreList = scoreList; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone();//淺克隆 } } }
Java中,克隆分爲深克隆與淺克隆。實現Cloneable接口,複寫Object.clone方法,並直接返回super.clone()是最簡單的,這是淺克隆——基本類型克隆值,引用類型克隆引用java
以上a1,a2...表示address1,address2...,即內存地址緩存
clone4.getScoreList().add之因此會拋異常,是由於clone2裏的list是Arrays.asList獲得的,他調用abstractList的add(E e)ide
public List<Integer> getScoreList() {//1 返回Arrays.ArrayList return scoreList; } public static Integer valueOf(int i) {//2 自動裝箱 if (i >= IntegerCache.low && i <= IntegerCache.high)//-128<= i <= 127,從緩存池中取 return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } public Integer(int value) { this.value = value; } public boolean add(E e) {//AbstractList.add(E e) add(size(), e); return true; } public void add(int index, E element) {//拋異常 throw new UnsupportedOperationException(); }
修正版this
/** * arraylist自己複寫了clone方法,string沒有 */ @Override protected Object clone() throws CloneNotSupportedException { User user = (User) super.clone(); if (scoreList instanceof ArrayList) {//ArrayList.class.isAssignableFrom(scoreList.getClass()) user.scoreList = (List<Integer>) ((ArrayList) scoreList).clone(); } return user; }
或rest
//序列化版 public class Interesting { public static void main(String[] args) throws IOException, ClassNotFoundException { User original = new User(); original.setUserId(1); original.setUserName("original"); List<Integer> scoreList = new ArrayList<>(); scoreList.add(11); scoreList.add(111); scoreList.add(1111); original.setScoreList(scoreList); //將對象寫到流裏 ByteArrayOutputStream bo=new ByteArrayOutputStream(); ObjectOutputStream oo=new ObjectOutputStream(bo); oo.writeObject(original); //從流裏讀出來 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); User user2 = (User) oi.readObject(); } static class User implements Serializable{ private static final long serialVersionUID = 9172109847523230489L; private int userId; private String userName; private List<Integer> scoreList; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public List<Integer> getScoreList() { return scoreList; } public void setScoreList(List<Integer> scoreList) { this.scoreList = scoreList; } } }