好玩的測試題

 

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

}

相關文章
相關標籤/搜索