4

某小厂Java面试题:深拷贝和浅拷贝区别了解吗?什么是引用拷贝?(图解) | JavaGuide

 2 years ago
source link: https://zhuanlan.zhihu.com/p/439228898
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

某小厂Java面试题:深拷贝和浅拷贝区别了解吗?什么是引用拷贝?(图解) | JavaGuide

思特沃克软件技术(武汉)有限公司 软件工程师

大家好,我是Guide!

今天给大家分享一个比较基础也是非常常见的 Java 面试题:“深拷贝和浅拷贝区别了解吗?什么是引用拷贝?”。

另外,本文也已经放到了我的网站:https://javaguide.cn/

关于深拷贝和浅拷贝区别,我这里先给结论:

  • 浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。
  • 深拷贝 :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。

上面的结论没有完全理解的话也没关系,我们来看一个具体的案例!

浅拷贝

浅拷贝的示例代码如下,我们这里实现了 Cloneable 接口,并重写了 clone() 方法。

clone() 方法的实现很简单,直接调用的是父类 Objectclone() 方法。

public class Address implements Cloneable{
    private final String name;
    // 省略构造函数、Getter&Setter方法
    @Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

public class Person implements Cloneable {
    private Address address;
    // 省略构造函数、Getter&Setter方法
    @Override
    public Person clone() {
        try {
            Person person = (Person) super.clone();
            return person;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
Person person1 = new Person(new Address("武汉"));
Person person1Copy = person1.clone();
// true
System.out.println(person1.getAddress() == person1Copy.getAddress());

从输出结构就可以看出, person1克隆对象person1 使用的仍然是同一个 Address 对象。

深拷贝

这里我们简单对 Person 类的 clone() 方法进行修改,连带着要把 Person 对象内部的 Address 对象一起复制。

@Override
public Person clone() {
    try {
        Person person = (Person) super.clone();
        person.setAddress(person.getAddress().clone());
        return person;
    } catch (CloneNotSupportedException e) {
        throw new AssertionError();
    }
}
Person person1 = new Person(new Address("武汉"));
Person person1Copy = person1.clone();
// false
System.out.println(person1.getAddress() == person1Copy.getAddress());

从输出结构就可以看出,虽然 person1 的克隆对象和 person1 包含的 Address 对象已经是不同的了。

那什么是引用拷贝呢? 简单来说,引用拷贝就是两个不同的引用指向同一个对象。

我专门画了一张图来描述浅拷贝、深拷贝、引用拷贝:

再分享一下我整理汇总的一些 Java 面试相关的 PDF 资料(质量很高!不要在看网上的哪些东拼西凑的垃圾面试题了!!!),希望对需要的小伙伴有帮助!

如何获取?

另外,完整的 Java 学习路线看这个:

再给大家推荐一个学习 Java 和准备Java 面试的网站(强烈推荐!这波自夸...):

我是 Guide哥,一个工作两年有余,接触编程已经6年有余的程序员。大三开源SnailClimb/JavaGuide (如果无法访问Github,可以访问国内的码云:SnailClimb/JavaGuide),目前已经 110k+ Star。未来几年,希望持续完善 JavaGuide,争取能够帮助更多学习 Java 的小伙伴!共勉!凎!

原创不易,欢迎点赞分享,欢迎关注 @JavaGuide,我会持续分享原创干货~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK