关于Clone 的方法使用

时间:2023-03-08 23:25:15
关于Clone 的方法使用

package cn.hncu.day7.clone.v1;
//克隆的套路:
// 第1步:重写User类的clone()方法,以供外面调用。因为外面的类无法直接调用User类父类中的clone()方法--protected
// 第2步:让User类实现Cloneable接口,否则clone时会抛出异常
// 第3步:在需要进行克隆的其它类中调用:User u2 = (User)user.clone()

//一个类的对象要想能够被clone,那么该类必须要实现Cloneable接口,否则clone时会抛出异常
public class User implements Cloneable{
private String name;
private int age;

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

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

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 "User [name=" + name + ", age=" + age + "]";
}

}

--------------------------------------------------

package cn.hncu.day7.clone.v1;

public class CloneDemo {

public static void main(String[] args) {
User user = new User("Jack",23);
System.out.println(user);

try {
User user2 = (User)user.clone();//该clone()方法必须是User类自己的,不能调用它的父类Object中的clone()方法,因为权限是protected--只有user对象自己克(在User类中能够调用它的clone)
user2.setAge(100);
System.out.println(user2);
System.out.println(user);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}

-------------------------------------------------------------

package cn.hncu.day7.clone.v2;

public class User implements Cloneable{
private String name;
private int age;

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

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

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 "User [name=" + name + ", age=" + age + "]";
}

}

----------------------------------------------------------------------

package cn.hncu.day7.clone.v2;
//该v2版本是有问题的---浅拷贝问题
//※※注意,简单的clone是浅拷贝,如果对象当中的成员变量是引用类型,那么这样的变量是捆绑的--克隆体和原型对象

public class Account implements Cloneable{
private User user;// 账户对应的用户
private double balance;// 余额

public Account(User user, double balance) {
super();
this.user = user;
this.balance = balance;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public double getBalance() {
return balance;
}

public void setBalance(double balance) {
this.balance = balance;
}

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

@Override
public String toString() {
return "Account [user=" + user + ", balance=" + balance + "]";
}

}

-------------------------------------------------------------------------------------------

package cn.hncu.day7.clone.v2;

public class CloneDemo {

public static void main(String[] args) {
User user = new User("Jack",23);
Account account = new Account(user, 100);
System.out.println(account);
try {
Account account2 = (Account)account.clone();
account2.setBalance(200);
account2.getUser().setName("Tom");
System.out.println(account2);
System.out.println(account);

} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}

-----------------------------------------------------------------------

package cn.hncu.day7.clone.v3;

public class User implements Cloneable{
private String name;
private int age;

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

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

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 "User [name=" + name + ", age=" + age + "]";
}

}

---------------------------------

package cn.hncu.day7.clone.v3;
//相比v2版本,我们解决浅拷贝问题就是修改这一个类.
//※※如果一个类中的变量都是primitive(基本数据类型或final型的引用类型),重写的克隆方法直接调用super.clone()就OK
//※※如果一个类中含有引用变量,那么克隆方法就如这个类所写---把浅copy的引用指向原型对象新的克隆体。

public class Account implements Cloneable{
private User user;// 账户对应的用户
private double balance;// 余额

public Account(User user, double balance) {
super();
this.user = user;
this.balance = balance;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override//深克隆
public Object clone() throws CloneNotSupportedException {
Account a =(Account) super.clone();

if(user!=null){
//※※把浅copy的引用指向原型对象新的克隆体。
a.user =(User)user.clone();
}
return a;
}

@Override
public String toString() {
return "Account [user=" + user + ", balance=" + balance + "]";
}

}

-------------------------------------------

package cn.hncu.day7.clone.v3;

public class CloneDemo {

public static void main(String[] args) {
User user = new User("Jack",23);
Account account = new Account(user, 100);
System.out.println(account);
try {
Account account2 = (Account)account.clone();
account2.setBalance(200);
account2.getUser().setName("Tom");
System.out.println(account2);
System.out.println(account);

} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}