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 | 否 |