JAVA后端面试《对象拷贝》

1.为什么要使用克隆?

  • 想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了,Java语言中的克隆针对的是类的实例。

2.如何实现对象克隆?

有以下两种方法:

  • 1.实现Cloneable接口并重写Object的clone方法。
  • 2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的克隆,代码如下:
package com.springCloud.consumer.controller;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;

import java.io.*;

/**
 * 克隆工具类
 */
public class MyUtil {
    private MyUtil(){
        throw new AssertionError();
    }
    @SuppressWarnings("unchecked")
    //此注解告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
    public static <T extends Serializable> T clone(T obj) throws Exception{
        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();
        // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    }
}
/*Person类*/
@Data
@AllArgsConstructor
@ToString
class Person implements Serializable{
   private static final long serialVersionUID = -9102017020286042305L;
   private String name;
   private int age;
   private Car car;
}
/*Car类*/
@Data
@AllArgsConstructor
@ToString
class Car implements Serializable{
    private static final long serialVersionUID = -5713945027627603702L;
    private String brand;
    private int maxSpeed;
}

/**
 * 克隆测试类
 */
class CloneTest{
    public static void main(String[] args) {
        Person p1 = new Person("张三",22,new Car("Benz",300));
        try {
            Person p2 = MyUtil.clone(p1);
            p2.getCar().setBrand("BYD");
            p2.getCar().setMaxSpeed(180);
            System.out.println("p1 = " + p1);
            System.out.println("----------");
            System.out.println("p2 ="  + p2);
             /*修改克隆的Person对象p2关联的汽车对象的品牌属性
              原来的Person对象p1关联的汽车不会受到任何影响
              因为在克隆Person对象时其关联的汽车对象也被克隆了*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*输出结果:
                p1 = Person(name=张三, age=22, car=Car(brand=Benz, maxSpeed=300))
                        ----------
                p2 =Person(name=张三, age=22, car=Car(brand=BYD, maxSpeed=180))*/
              
             

}

3.深拷贝和浅拷贝的区别是什么?

  • 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中一个对象的某个值,另外一个对象的对应值都会随之变化,这就是浅拷贝(例:assign())。
  • 深拷贝是将对象和值复制过来,修改其中一个对象的某个值,另外一个对象的对应值不会随之改变,这就是深拷贝(例:JSON.parse()和JSON.stringify()方法)
发布了18 篇原创文章 · 获赞 6 · 访问量 1859

猜你喜欢

转载自blog.csdn.net/weixin_43766298/article/details/104157414