在Java语言中,当我们需要拷贝一个Java对象的时候,常见的会有两种方式的拷贝:浅拷贝与深拷贝。
浅拷贝代码演示(最常见的方式):
/**
* 浅拷贝:拷贝的就是目标对象在堆内存中的地址
* 注意:拷贝对象改变,源对象(目标对象)改变
*/
public class SlowCopy {
public static void main(String[] args) {
User user = new User();
user.setUserName("张三");
user.setPassWord("123456");
//浅拷贝
User user1 = user ;
System.out.println(user); //com.sqx.copy.bean.User@1b6d3586
System.out.println(user1); //com.sqx.copy.bean.User@1b6d3586
}
}
深拷贝的对象修改的时候,源对象是不受影响的!
一般常用的深拷贝方式有如下5种
1、构造函数方式
/**
* 构造器实现深拷贝 :我们拷贝对象和源对象是隔离的,互不干扰!
*/
public class DeepCopy {
public static void main(String[] args) {
//深拷贝
User user = new User("张三","123456");
User user1 = new User("李四","654321");
System.out.println(user); //com.sqx.copy.bean.User@1b6d3586
System.out.println(user1); //com.sqx.copy.bean.User@4554617c
}
}
2、重写Clone方法
1、实现Cloneable接口,Cloneable其实就是一个标记接口,只有实现这个接口后,然后在类中重写Object中的clone方法,然后通过类
调用clone方法才能克隆成功,如果不实现这个接口,则会抛出CloneNotSupportedException(克隆不被支持)异常。
public class Student implements Cloneable {
private String userName ;
private String passWord ; // 此处省略set\get方法
@Override
public Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
}
2、代码演示深拷贝
/**
* 重写clone方法实现深拷贝
*/
public class DeepCopy01 {
public static void main(String[] args) {
Student student01 = new Student("张三","123456");
Student student02 = null;
try {
student02 = student01.clone(); // 深拷贝对象
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(student01); //com.sqx.copy.bean.Student@1b6d3586
System.out.println(student02); //com.sqx.copy.bean.Student@4554617c
System.out.println(student01.equals(student02)); // true 标识内容相同,但是仅地址不同(记得重写equlas)
}
}
我们发现拷贝的student02对象和源对象地址已经不同了,但是内容是一致的~
补充
我们的ArrayList 、LinkedList等都实现了Cloneable接口,支持深拷贝
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
...
}
样例演示:
public class ArrayListCopyTest {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
User user = new User("张三", "123456");
list.add(user) ;
System.out.println("list: "+list); //源ArrayList对象
ArrayList<User> clone = (ArrayList<User>) list.clone();
System.out.println("clone: "+clone); //经过深拷贝得到的ArrayList对象
System.out.println(list == clone); // false 经过深拷贝,创建的是新的对象
System.out.println(list.get(0) == clone.get(0)); //true 说明拷贝对象和源对象的内容是一样的!
}
}
总结:
实现深拷贝的方式还有:Apache Commons Lang序列化、Gson序列化、jackson序列化等
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/m0_46571920/article/details/123012610
内容来源于网络,如有侵权,请联系作者删除!