java如何对一个对象实现深拷贝?

  经常面试的时候会被问到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

 

     

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值