为什么需要克隆:因为实例(对象)是引用传递,不管赋值多少个 都是一个
package prototype.prototype2;
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student("晓峰",21);
Student student2 = student1;
System.out.println(student1);
System.out.println(student2);
student1.setName("晓畅");
System.out.println(student1);
System.out.println(student2);
/**
* Student{name='晓峰', age=21}
* Student{name='晓峰', age=21}
* Student{name='晓畅', age=21}
* Student{name='晓畅', age=21}
*/
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
内存示意图:
修改了sutdnet1中的name student2 的也会改变 ,因为student1和student2 指向的内存空间是一块
我们想要的是student1和student2 分别指向的两块内存 ,所以就出现了克隆
先说下java如何实现克隆:
1.实现 Cloneable接口,并重写clone方法
class Student implements Cloneable{
...
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
2.自己写clone
class Student{
...
public Object clone(){
Schoolbag schoolbagclone = new Schoolbag(this.schoolbag.getSize(),this.schoolbag.getColor());
Student studentclone = new Student(this.name,this.age,schoolbagclone);
return studentclone;
}
}
克隆操作的代码:
package prototype.prototype2;
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student("晓峰",21);
Student student2 = student1.clone();
System.out.println(student1);
System.out.println(student2);
student1.setName("晓畅");
System.out.println(student1);
System.out.println(student2);
/**
* Student{name='晓峰', age=21}
* Student{name='晓峰', age=21}
* Student{name='晓畅', age=21}
* Student{name='晓峰', age=21}
*/
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
public Student clone() {
Student studentclone = new Student(this.name, this.age);
return studentclone;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
内存示意图:
这就是克隆的方式了,不过还存在一个问题,就是套娃,如果一个类中的属性存在非简单值类型,就要小心了,就要实现深拷贝
package prototype.prototype1;
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
Schoolbag schoolbag = new Schoolbag("大","红色");
Student student = new Student("晓峰",13,schoolbag);
Student student1 = (Student)student.clone();
student.setAge(23);
student.getSchoolbag().setColor("蓝色");
System.out.println(student);
System.out.println(student1);
}
}
class Student{
private String name;
private int age;
private Schoolbag schoolbag;
public Student(String name, int age, Schoolbag schoolbag) {
this.name = name;
this.age = age;
this.schoolbag = schoolbag;
}
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;
}
public Schoolbag getSchoolbag() {
return schoolbag;
}
public void setSchoolbag(Schoolbag schoolbag) {
this.schoolbag = schoolbag;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", schoolbag=" + schoolbag +
'}';
}
public Object clone(){
Schoolbag schoolbagclone = new Schoolbag(this.schoolbag.getSize(),this.schoolbag.getColor());
Student studentclone = new Student(this.name,this.age,schoolbagclone);
return studentclone;
}
}
class Schoolbag{
private String size;//l xl xxl
private String color;
public Schoolbag(String size, String color) {
this.size = size;
this.color = color;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Schoolbag{" +
"size='" + size + '\'' +
", color='" + color + '\'' +
'}';
}
public Object clone(){
Schoolbag schoolbagclone = new Schoolbag(this.size,this.color);
return schoolbagclone;
}
}
内存示意图就不画了自己脑补吧