下面我将为你详细讲解如何实现Java克隆的三种方式。
1. Java实现克隆的三种方式
在Java中,对象的克隆可以通过直接复制或者序列化来完成。实现Java对象克隆一般有三种方式:
1.1. 浅克隆
浅克隆只复制了对象本身,不包括对象中的引用类型字段。假设有一个简单的Person类,它包括一个基本类型和一个引用类型字段:
public class Person implements Cloneable{
private String name;
private Integer age;
private List<String> hobbies;
//省略构造方法和get、set方法
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
如果使用浅克隆方法克隆出一个Person对象,那么hobbies字段只是复制了原始对象中引用的地址,而不是实际的引用对象本身。因此,对克隆对象中的hobbies字段的修改会影响原始对象。
下面是一个Person对象的浅克隆示例:
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person();
p1.setName("张三");
p1.setAge(20);
List<String> hobbies = new ArrayList<>();
hobbies.add("足球");
hobbies.add("音乐");
p1.setHobbies(hobbies);
Person p2 = (Person) p1.clone();
System.out.println("p1:" + p1);
System.out.println("p2:" + p2);
p2.setName("李四");
p2.getHobbies().add("看书");
System.out.println("p1:" + p1);
System.out.println("p2:" + p2);
}
}
输出结果:
p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p1:Person{name='张三', age=20, hobbies=[足球, 音乐, 看书]}
p2:Person{name='李四', age=20, hobbies=[足球, 音乐, 看书]}
1.2. 深克隆
深克隆会复制对象中的所有引用类型字段。假设有一个Order类,它包括一个基本类型字段和一个引用类型Hobby类型字段:
public class Order implements Cloneable {
private String orderId;
private Hobby hobby;
//省略构造方法和get、set方法
@Override
protected Object clone() throws CloneNotSupportedException {
Order order = (Order)super.clone();
order.setHobby((Hobby) hobby.clone());
return order;
}
}
若使用深克隆方式实现Order类对象的复制,则实际上是将原始对象中各引用指向对象的数据区域都复制过来了,因此修改了克隆对象中的引用类型字段不会影响原始对象。
下面是一个Order对象的深克隆示例:
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Order order1 = new Order();
order1.setOrderId("20211014");
Hobby hobby = new Hobby();
hobby.setName("读书");
order1.setHobby(hobby);
Order order2 = (Order) order1.clone();
System.out.println("order1:" + order1);
System.out.println("order2:" + order2);
order2.getHobby().setName("看电影");
System.out.println("order1:" + order1);
System.out.println("order2:" + order2);
}
}
输出结果:
order1:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order2:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order1:Order{orderId='20211014', hobby=Hobby{name='读书'}}
order2:Order{orderId='20211014', hobby=Hobby{name='看电影'}}
1.3. 序列化克隆
序列化克隆会通过序列化和反序列化技术实现对象的克隆。要实现序列化克隆,需要让对象实现Serializable接口,并将对象序列化到一个流中,然后再从流中反序列化出一个新的对象。
下面是一个Person对象的序列化克隆示例:
public static <T extends Serializable> T clone(T obj) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
T newObj = (T)ois.readObject();
return newObj;
}
public static void main(String[] args) throws Exception {
Person p1 = new Person();
p1.setName("张三");
p1.setAge(20);
List<String> hobbies = new ArrayList<>();
hobbies.add("足球");
hobbies.add("音乐");
p1.setHobbies(hobbies);
Person p2 = clone(p1);
System.out.println("p1:" + p1);
System.out.println("p2:" + p2);
p2.setName("李四");
p2.getHobbies().add("看书");
System.out.println("p1:" + p1);
System.out.println("p2:" + p2);
}
输出结果:
p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p1:Person{name='张三', age=20, hobbies=[足球, 音乐]}
p2:Person{name='李四', age=20, hobbies=[足球, 音乐, 看书]}
以上是实现Java克隆的三种方式,根据实际需要可以选择不同的方式进行对象的克隆。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现克隆的三种方式实例总结 - Python技术站