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;
    }
}

输出结果:

目录
相关文章
|
4天前
|
SQL Java
java面试题笔试常见选择题大全含答案
java面试题笔试常见选择题大全含答案
|
4天前
|
SQL JavaScript Java
java程序员面试题大全含答案(2018--2019)
java程序员面试题大全含答案(2018--2019)
|
4天前
|
设计模式 开发框架 Java
java设计模式面试题大全含答案
java设计模式面试题大全含答案
|
4天前
|
设计模式 SQL JavaScript
java面试宝典全套含答案
java面试宝典全套含答案
|
4天前
|
存储 Java
java面试题大全带答案_面试题库_java面试宝典2018
java面试题大全带答案_面试题库_java面试宝典2018
|
4天前
|
SQL 前端开发 Java
2019史上最全java面试题题库大全800题含答案(面试宝典)(4)
2019史上最全java面试题题库大全800题含答案(面试宝典)
|
4天前
|
缓存 安全 Java
Java线程面试题含答案
Java线程面试题含答案
|
4天前
|
SQL Java 数据库连接
2019史上最全java面试题题库大全800题含答案(面试宝典)(2)
2019史上最全java面试题题库大全800题含答案(面试宝典)
|
4天前
|
存储 设计模式 Java
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
|
4天前
|
SQL 算法 安全
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
java面试宝典_java基础面试_2018java面试题_2019java最新面试题