1. 程式人生 > 其它 >java 淺拷貝和深拷貝

java 淺拷貝和深拷貝

java 淺拷貝和深拷貝

目錄

簡單理解:

淺拷貝:拷貝地址。原變數改變,新變數也會受到影響

深拷貝:拷貝值,開闢一塊新的記憶體返回。原變數改變,新變數不會受到影響

拷貝基本資料型別

拷貝基本資料型別字面量,都是拷貝值

拷貝引用型別

淺拷貝:

  1. 直接賦值,直接返回的是克隆物件的引用地址

    測試程式碼:

    public class User {
        public User(Integer age) {
            this.age = age;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        private Integer age;
        public static void main(String[] args) {
            User user = new User(10);
            User user2 = user;
            user2.setAge(100);
            System.out.println(user == user2); // true
            System.out.println(user.getAge()); // 100
        }
    }
    
    
  2. Cloneable介面
    測試程式碼:

    public class User implements Cloneable {
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        private Integer age;
        private String name;
        private int height;
        private Son son;
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
        public Son getSon() {
            return son;
        }
    
        public void setSon(Son son) {
            this.son = son;
        }
    
        public User(Integer age, String name, int height, Son son) {
            this.age = age;
            this.name = name;
            this.height = height;
            this.son = son;
        }
    
        public static void main(String[] args) throws CloneNotSupportedException {
            User user = new User(10, "name", 180, new Son("xxx"));
            User user2 = (User) user.clone();
            user2.getSon().setName("yyy");
            System.out.println(user.getSon() == user2.getSon()); // true
            System.out.println(user.getSon().getName()); // yyy
        }
    }
    

深拷貝:

  1. Cloneable的clone其實只能拷貝一層(就是和直接賦值不相同的是,user = user2,user和user2地址一樣,clone是user和user2的地址不一樣,裡面的東西一樣),如果我們重寫clone,遍歷層級進行clone就可達到深拷貝
  2. 各種序列化拷貝,例如:JSON序列化,Object序列化流,需要實現Serializable介面,速度相對慢
    注意點:被transient修飾不參與序列化

不可變類的特殊性:

例如像這種String、包裝類,這種都是不可變類,它們不能改變內容,如果要改變,是開闢新的記憶體,返回地址,而不是改變記憶體裡的資料,所以不可變類的拷貝都是引用的地址