经常面试的时候会被问到Java的深拷贝和浅拷贝的区别,以及如何实现一个深拷贝?(是不是熟悉的味道)
Java的对象拷贝分为两种情况:浅拷贝和深拷贝
浅拷贝:指的是拷贝的当前对象的地址引用,这种拷贝当原对象值发生变化时,拷贝对象的值也会跟随变化
深拷贝:相对于浅拷贝而言,深拷贝拷贝的是原对象的值,简单理解就是当原对象的值发生变化时,拷贝对象的值是不会跟随变化的
基础类代码
创建一个Question类
public class Question { private String title; private String content; private Answer answer; public Question(){ } public Question(String title, Answer answer) { this.title = title; this.content = content; this.answer = answer; }
创建一个Answer类
public class Answer { private String answerContent; public Answer(){} public Answer(String answerContent) { this.answerContent = answerContent; }}
1 浅拷贝的实现方式:
1.1 复制的方式
User user = new User();
User cloneUser = user;
1.2 实现Java的Cloneable接口,并重新clone方法,但是里面的熟悉不重写
public class Question implements Cloneable, Serializable { private String title; private String content; private Answer answer; @Override protected Question clone() throws CloneNotSupportedException { Question cloneQuestion = (Question)super.clone(); return cloneQuestion; }// 省略set/get方法
}
2 深拷贝的实现方式:
2.1 构造器方式实现
public static void constructTest(){ Question question = new Question(); question.setTitle("2021编程语言排行榜中什么语最受欢迎?"); Answer answer = new Answer(); answer.setAnswerContent("Python"); question.setAnswer(answer); Question copyQuestion = new Question(question.getTitle(),new Answer(answer.getAnswerContent())); answer.setAnswerContent("java"); System.out.println("constructTest:"+copyQuestion.getAnswer().getAnswerContent().equals(question.getAnswer().getAnswerContent())); }
2.2 实现Java Object的Cloneable接口,并重新clone方法
public class Question implements Cloneable { private String title; private String content; private Answer answer; @Override protected Question clone() throws CloneNotSupportedException { Question cloneQuestion = (Question)super.clone(); // 这里的Answer也要实现Cloneable 并重写clone方法 cloneQuestion.setAnswer(answer.clone()); return cloneQuestion; }}
2.3 实现Serializable,利用序列化和反序列化方式创建对象
public class Question implements Serializable { private static final long serialVersionUID = 1691032820955124193L; private String title; private String content; private Answer answer;}
2.3.1 利用org.apache.commons.lang3.SerializationUtils 工具实现
public static void serializableCopy(){ Question question = new Question(); question.setTitle("2021编程语言排行榜中什么语最受欢迎?"); Answer answer = new Answer(); answer.setAnswerContent("Python"); question.setAnswer(answer); Question cloneQuestion = SerializationUtils.clone(question); question.getAnswer().setAnswerContent("java"); System.out.println("serializableCopy:"+cloneQuestion.getAnswer().getAnswerContent() + "=="+ question.getAnswer().getAnswerContent()); }
还有其他方式:如Gson Jackson等方式,您可以自行研究研究哈
参考:https://www.cnblogs.com/mjn1/p/12990072.html