java深拷貝和淺拷貝

java 中的複製

淺拷貝和深拷貝之前的區別

  • 淺拷貝只會將引用賦值,指向原來的對象地址,拷貝後內存中還是一個對象。
  • 深拷貝會複製引用的對象,拷貝後內存有兩個對象。(原生clone方法只能複製第一層,如有嵌套對象,則淺拷貝,嵌套的對象,因此需要重寫clone自己處理)

測試代碼

  • javaBean
public class User implements Cloneable {

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public String toString() {
        return "內存地址 " + Integer.toHexString(hashCode()) +
                " User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 測試複製代碼
              User user = new User("xiaoMing", 3);
                User user1 = user;                  //淺複製
                User user2 = (User) user.clone();   //深複製
                user.setName("newName");
                user.setAge(100);
                Log.i(TAG, "user = " + user);
                Log.i(TAG, "user1 = " + user1);
                Log.i(TAG, "user2 = " + user2);
  • 測試結果
user = 內存地址 3f41c6 User{name='newName', age=100}
user1 = 內存地址 3f41c6 User{name='newName', age=100}
 user2 = 內存地址 61d8587 User{name='xiaoMing', age=3}
  • 結果分析
對象 複製類別 結果
user1 淺複製 對象地址未變
user2 深複製 對象地址改變

Array相關的方法

array中有些方法,是不是深拷貝呢,驗證一下

方法一


    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
  • 代碼驗證
             User a = new User("a", 1);
                User b = new User("b", 2);
                User c = new User("c", 3);
                User[] users = {a, b, c};
                User[] copyed = new User[3];
                for (User user : users) {
                    Log.i(TAG, "user" + user);
                }
                System.arraycopy(users, 0, copyed, 0, 3);

                a.setName("NewNameA");
                b.setName("NewNameB");
                c.setName("NewNameC");

                for (User user : copyed) {
                    Log.i(TAG, "user" + user);
                }
  • 結果輸出
user內存地址 3f41c6 User{name='a', age=1}
user內存地址 61d8587 User{name='b', age=2}
user內存地址 6ab2cb4 User{name='c', age=3}
copyed內存地址 3f41c6 User{name='NewNameA', age=1}
copyed內存地址 61d8587 User{name='NewNameB', age=2}
copyed內存地址 6ab2cb4 User{name='NewNameC', age=3}

結論:arraycopy是淺拷貝

方法二

Arrays.copyOf(elementData, size, Object[].class);
  • 測試代碼
         User a = new User("a", 1);
                User b = new User("b", 2);
                User c = new User("c", 3);
                User[] users = {a, b, c};
                User[] copyed;
                for (User user : users) {
                    Log.i(TAG, "user" + user);
                }
                copyed = Arrays.copyOf(users, 3);
                a.setName("NewNameA");
                b.setName("NewNameB");
                c.setName("NewNameC");

                for (User user : copyed) {
                    Log.i(TAG, "copyed" + user);
                }
  • 結果輸出
user內存地址 3f41c6 User{name='a', age=1}
user內存地址 61d8587 User{name='b', age=2}
user內存地址 6ab2cb4 User{name='c', age=3}
copyed內存地址 3f41c6 User{name='NewNameA', age=1}
copyed內存地址 61d8587 User{name='NewNameB', age=2}
copyed內存地址 6ab2cb4 User{name='NewNameC', age=3}
  • 結論
    Arrays.copyOf 也是淺複製

結論

方法 是否深複製
System.arraycopy
Arrays.copyOf
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章