java的克隆

所谓复制就是将一份东西拷贝一份,在java中有浅复制和深复制的概念
浅复制是指被复制的对象与原对象有相同的成员变量值,但是其引用类型的变量还是指的同
一个对象,而深复制是对原对象及其成员变量引用的对象也复制了一遍

复制产生的条件要满足如下
第一要实现Cloneable接口,重写Object类的clone方法并将其protect修饰符修改为public,调用Object类中的clone方法super.clone()
有人可能会问为什么一定要调用super.clone()
在运行时刻,Object中的clone方法识别出你要复制的是哪一个对象,然后为此对象分配空
间,并进行对象的复制,将原始对象的内容复制到新对象的存储空间中
下面是一个深复制的例子

package com.lamp.test;

public class CloneTest {
public static void main(String[] args) throws Exception {
Teacher teacher = new Teacher();
teacher.setAge(50);
teacher.setName("胡老师");

Student student = new Student();
student.setAge(22);
student.setName("zhansan");
student.setTeacher(teacher);

Student student2 = (Student)student.clone();
student2.getTeacher().setName("吴老师"); //由于是深复制,所以此处对teacher成员变量的修改不会对student有影响
System.out.println(student2.getName());
System.out.println(student.getTeacher().getName());
}
}

class Student implements Cloneable {
private int age;

private String name;

private Teacher teacher;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Teacher getTeacher() {
return teacher;
}

public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}

@Override
public Object clone() throws CloneNotSupportedException { //重写Object的clone方法,并要将其protect修饰符改为public
Student student = (Student) super.clone();
student.setTeacher((Teacher) student.getTeacher().clone());

//由于Object的clone为浅复制,所以在复制对象的引用时候,也要将引用所指的对象复制一遍
return student;
}
}

class Teacher implements Cloneable {
private int age;

private String name;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

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

}
### Java 克隆对象的实现方式:浅克隆与深克隆 Java 中的对象克隆功能是通过 `Cloneable` 接口和 `Object` 类中的 `clone()` 方法来实现的。以下是关于克隆功能的详细说明: #### 1. 浅克隆克隆是指克隆出的新对象会复制原对象的所有基本数据类型字段,但对于引用类型的字段,新对象只会复制引用地址,而不是创建新的对象实例。这意味着原对象和克隆对象共享同一个引用类型的对象。 以下是一个浅克隆的示例代码[^4]: ```java class Student implements Cloneable { public String name; public int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{name='" + name + "', age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Test { public static void main(String[] args) throws CloneNotSupportedException { Student student = new Student("张三", 18); Student student1 = (Student) student.clone(); System.out.println(student); // 输出: Student{name='张三', age=18} System.out.println(student1); // 输出: Student{name='张三', age=18} } } ``` #### 2. 深克隆克隆是指不仅复制基本数据类型的字段,还对引用类型的字段也进行递归复制,确保原对象和克隆对象没有任何引用共享。 深克隆可以通过手动实现或使用序列化机制来完成。以下是一个手动实现深克隆的示例代码[^1]: ```java class Person implements Cloneable { String name; int age; int[] scores; public Person(String name, int age, int[] scores) { this.name = name; this.age = age; this.scores = scores; } @Override public Person clone() { try { Person cloned = (Person) super.clone(); cloned.scores = cloned.scores.clone(); // 深克隆数组 return cloned; } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } } ``` 如果对象包含复杂的嵌套结构,可以递归调用每个子对象的 `clone()` 方法[^2]: ```java class Order implements Cloneable { private String orderId; private List<Item> items; @Override public Order clone() { try { Order cloned = (Order) super.clone(); cloned.items = new ArrayList<>(); for (Item item : this.items) { cloned.items.add(item.clone()); // 假设 Item 也实现了克隆 } return cloned; } catch (CloneNotSupportedException e) { throw new AssertionError(); } } } ``` #### 3. 使用序列化实现深克隆 另一种实现深克隆的方式是利用 Java 的序列化机制。这种方法适用于对象及其所有子对象都实现了 `Serializable` 接口的情况。 示例代码如下: ```java import java.io.*; public class DeepCopyUtil { public static <T> T deepClone(T obj) throws IOException, ClassNotFoundException { // 序列化 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); // 反序列化 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return (T) ois.readObject(); } } ``` #### 4. 注意事项 - **实现 Cloneable 接口**:必须让类实现 `Cloneable` 接口,否则调用 `clone()` 方法时会抛出 `CloneNotSupportedException` 异常[^1]。 - **覆盖 clone() 方法**:默认的 `clone()` 方法只执行浅克隆。如果需要深克隆,则需要手动处理引用类型的字段。 - **异常处理**:在实现 `clone()` 方法时,应捕获并处理 `CloneNotSupportedException` 异常。 - **特殊资源限制**:`clone()` 方法无法克隆线程、文件句柄等特殊资源。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值