java面试基础 -- 深克隆 & 浅克隆

简介: java面试基础 -- 深克隆 & 浅克隆


引例

       说到java的克隆你还记得多少? 一说到克隆你可能就会想起来那个接口, 没错, 他就是Cloneable

       Cloneable是java里面内置的很常用的接口, 我们说 Object类中也有一个clone方法:

        但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.

        于是, 我们创建一个类为Dog类, 如下:

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dog dog1 = new Dog();
        Dog dog2 = (Dog) dog1.clone();
        System.out.println(dog1 == dog2);
    }
}
 
class Dog implements Cloneable {
    public String dogName;
 
    public int dogAge;
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Dog newDog = null;
        newDog = (Dog) super.clone();
        return newDog;
    }
}

输出结果:




深克隆 vs 浅克隆

       浅克隆只复制对象本身和对象的本数据类型字段,而不复制引用类型字段所指向的对象.

这里的引用类型, 可以是类的引用, 也可以是字符串等.

       我们说实现了Cloneable接口的类拷贝出来的对象是浅拷贝还是深拷贝???

案例:

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Animal animal1 = new Animal();
        Animal animal2 = (Animal) animal1.clone();
        animal2.classIn = 2;
        animal2.dog.name = "小白";
        System.out.println(animal1.toString());
        System.out.println(animal2.toString());
    }
}
 
class Dog {
    String name = "小黑";
}
class Animal implements Cloneable {
    public Dog dog = new Dog();
 
    public int classIn = 1;
 
    @Override
    public String toString() {
        return "Animal{" +
                "dogName=" + dog.name +
                ", classIn=" + classIn +
                '}';
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

输出结果:

       可以看出来, 他们里面的类的实例却是共享的, 里面的类的引用不同, 但是引用的是同一个类对象. 这就是浅拷贝.




如何深克隆

深克隆基本数据类型变量和引用类型变量指向的对象都会被复制,即针对引用类型的成员变量真正的复制一份,重新开辟空间保存,这样两个引用类型属性互不影响。

       那么如何进行深拷贝呢??

        很容易想到的一点就是, 在重写object中的clone方法, 然后对被克隆的类里面的类引用继续克隆. 也就是嵌套克隆

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Animal animal1 = new Animal();
        Animal animal2 = (Animal) animal1.clone();
        animal2.classIn = 2;
        animal2.dog.name = "小白";
        System.out.println(animal1.toString());
        System.out.println(animal2.toString());
    }
}
 
class Dog implements Cloneable{
    String name = "小黑";
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Animal implements Cloneable {
    public Dog dog = new Dog();
 
    public int classIn = 1;
 
    @Override
    public String toString() {
        return "Animal{" +
                "dogName=" + dog.name +
                ", classIn=" + classIn +
                '}';
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Animal newAnimal = (Animal) super.clone();
        newAnimal.dog = (Dog) dog.clone();
        return  newAnimal;
    }
}

输出结果:

目录
相关文章
|
14天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
45 2
|
2天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
24 14
|
19天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
24天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
20天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
43 4
|
21天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
72 4
|
2月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
98 1
Java面试题之Java集合面试题 50道(带答案)
|
2月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
55 5
|
2月前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
23 1
|
2月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
30 3