创建对象的三种方式:
- 使用new创建对象 [将地址值存储到堆中,会出现OOM]
- 使用反射的方式创建对象 [不安全]
- 使用Object类中自带的clone方法
如何使用clone呢?
- 第一步在对象类中实现Cloneable接口 [标识符]
- 第二步在对象类中重写clone方法
- 第三步创建对象调用clone方法
- 浅拷贝 [Java中默认的就是浅拷贝]
clone出来的对象不一样,但是其中的成员变量中对象是同一个 [所为的浅拷贝]
存在的危害:
因为里面的成员变量对象地址是一样的,如果修改其中的成员变量的属性值的话,
两个对象的值都会发生变化
建议:
如果需要使用拷贝方法,建议使用深拷贝
- 深拷贝
- 将CloneModel类中的 Student类 也实现Cloneable方法,并且加强其中的clone方法
public class Student implements Cloneable {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "CloneModel{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public Student clone() throws CloneNotSupportedException {
//从Object类中 强制转换成 Student类
return (Student)super.clone();
}
/* @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}*/
}
2.加强CloneModel类中的clone方法
public class CloneModel implements Cloneable {
private String name;
private int age;
private Student student;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setStudent(Student student) {
this.student = student;
}
public CloneModel(String name, int age) {
this.name = name;
this.age = age;
}
public CloneModel(String name, int age, Student student) {
this.name = name;
this.age = age;
this.student = student;
}
@Override
public String toString() {
return "CloneModel{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public CloneModel clone() throws CloneNotSupportedException {
//继承父类方法,并且进行强制转化
CloneModel clone = (CloneModel) super.clone();
clone.setStudent(student.clone());
return clone;
}
/* @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}*/
public static void main(String[] args) throws CloneNotSupportedException {
/* CloneModel cloneModel = new CloneModel("无敌", 12);
//除了 使用 new 创建对象 以及反射创建对象 还可以使用 Object 中的clone方法
System.out.println("hash值:" + cloneModel.hashCode() + "---" + cloneModel);
CloneModel clone = (CloneModel) cloneModel.clone();
System.out.println("hash值:" + clone.hashCode() + "---" + clone);*/
/*
System.out.println("-------------------------------------");
//浅拷贝
CloneModel cloneModel1 = new CloneModel("浅拷贝", 123, new Student("angle", 13));
System.out.println(cloneModel1 + "---自己的hash值" + "t" + cloneModel1.hashCode() + "t" + "成员变量中的hash值" + "t" + cloneModel1.student.hashCode());
CloneModel clone1 = (CloneModel) cloneModel1.clone();
System.out.println(clone1 + "---自己的hash值" + "t" + clone1.hashCode() + "t" + "成员变量中的hash值" + "t" + clone1.student.hashCode());*/
System.out.println("-------------------------------------");
//深拷贝
CloneModel cloneModel2 = new CloneModel("浅拷贝", 123, new Student("angle", 13));
System.out.println(cloneModel2 + "---自己的hash值" + "t" + cloneModel2.hashCode() + "t" + "成员变量中的hash值" + "t" + cloneModel2.student.hashCode());
CloneModel clone = cloneModel2.clone();
System.out.println(clone + "---自己的hash值" + "t" + clone.hashCode() + "t" + "成员变量中的hash值" + "t" + clone.student.hashCode());
}
}
3.测试数据
总结:
如果需要使用到clone的话,使用深拷贝