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; } } }