在Java中对对象的复制分为2种:浅复制和深复制。
浅复制:仅复制目标对象的引用,共享同一内存对象。所以,对原对象的修改同样作用于复制的对象,反过来也一样。
深复制:相当于重新创建一个和原对象相同类型的对象,并复制原对象的属性方法等。
例1:浅复制
首先创建 User,java 类
package com.clonetest;
public class User{
private String username;
private String password;
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
创建测试类 CloneTestSimple.java
package com.clonetest;
public class CloneTestSimple {
public static void main(String[] args) {
// Create User and initialize
User user = new User();
user.setUsername("Tom");
user.setPassword("tom");
// Clone User Object and output parameters
User cloneUser;
cloneUser = user;
System.out.println("================ New clone user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
// Update user
user.setUsername("Jerry");
user.setPassword("Jerry");
System.out
.println("================ After update user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
// Update cloneUser
cloneUser.setUsername("Tom an Jerry");
cloneUser.setPassword("Tom and Jerry");
System.out
.println("================ After update clone user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
}
}
测试结果如下:
================ New clone user ===============
Origin user: Tom, tom
Clone user: Tom, tom
================ After update user ===============
Origin user: Jerry, Jerry
Clone user: Jerry, Jerry
================ After update clone user ===============
Origin user: Tom an Jerry, Tom and Jerry
Clone user: Tom an Jerry, Tom and Jerry
例2:深复制
2.1 通过实现 Cloneable 接口,重写 clone 方法实现:
改写上例中的 User.java 类
package com.clonetest;
public class User implements Cloneable{
private String username;
private String password;
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Object clone(){
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
改写测试类 CloneTestSimple.java :
package com.clonetest;
public class CloneTestSimple {
public static void main(String[] args) {
// Create User and initialize
User user = new User();
user.setUsername("Tom");
user.setPassword("tom");
// Clone User Object and output parameters
User cloneUser;
cloneUser = (User) user.clone();
System.out.println("================ New clone user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
// Update user
user.setUsername("Jerry");
user.setPassword("Jerry");
System.out
.println("================ After update user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
// Update cloneUser
cloneUser.setUsername("Tom an Jerry");
cloneUser.setPassword("Tom and Jerry");
System.out
.println("================ After update clone user ===============");
System.out.println("Origin user: " + user.getUsername() + ", "
+ user.getPassword());
System.out.println("Clone user: " + cloneUser.getUsername() + ", "
+ cloneUser.getPassword());
}
}
测试结果如下:================ New clone user ===============
Origin user: Tom, tom
Clone user: Tom, tom
================ After update user ===============
Origin user: Jerry, Jerry
Clone user: Tom, tom
================ After update clone user ===============
Origin user: Jerry, Jerry
Clone user: Tom an Jerry, Tom and Jerry
2.2 通过实现 Serializable 接口,用序列化和反序列化实现:
创建测试类 Account.java
package com.clonetest;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Account implements Serializable {
private String firstname;
private String lastname;
public Account(){}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
改写测试类 CloneTestSimple.java :package com.clonetest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class CloneTestSimple {
public static void main(String[] args) {
Account account = new Account();
account.setFirstname("Sherlock");
account.setLastname("Homles");
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(account);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Account cloneAccount = (Account) ois.readObject();
System.out.println("================ New clone account ===============");
System.out.println("Origin account: " + account.getFirstname() + ", "
+ account.getLastname());
System.out.println("Clone account: " + cloneAccount.getFirstname() + ", "
+ cloneAccount.getLastname());
account.setFirstname("William");
account.setLastname("Shakespeare");
System.out.println("================ update origin account ===============");
System.out.println("Origin account: " + account.getFirstname() + ", "
+ account.getLastname());
System.out.println("Clone account: " + cloneAccount.getFirstname() + ", "
+ cloneAccount.getLastname());
cloneAccount.setFirstname("Will");
cloneAccount.setLastname("Smith");
System.out.println("================ update clone account ===============");
System.out.println("Origin account: " + account.getFirstname() + ", "
+ account.getLastname());
System.out.println("Clone account: " + cloneAccount.getFirstname() + ", "
+ cloneAccount.getLastname());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
测试结果如下:================ New clone account ===============
Origin account: Sherlock, Homles
Clone account: Sherlock, Homles
================ update origin account ===============
Origin account: William, Shakespeare
Clone account: Sherlock, Homles
================ update clone account ===============
Origin account: William, Shakespeare
Clone account: Will, Smith