Java对象的传递引用、浅拷贝、深拷贝的具体区别

Java中对象的传递引用、浅拷贝、深拷贝之间区别

What are they?

传递引用: 即两个或多个对象名称指向同一段使用new关键字开辟的地址空间,它们都可以对此地址空间内的对象进行操作,即两个对象是相等的。

如:

Sheep sheep = new Sheep("tom",1,"white");
Sheep sheep1 = sheep;

演示图如下:

在这里插入图片描述

浅拷贝: 即原类对象需实现Cloneable接口,通过调用已有对象的clone()方法重新开辟一段内存空间建立对象,但是,对于对象内的引用数据类型,不进行拷贝,只是将新的对象内的引用数据类型也指向原本的地址空间,实现了两个对象的不等。

如(sheep对象内的sheepfriends对象也为Sheep类):

Sheep sheep = new Sheep("tom",1,"white");
sheep.sheepFriends = new Sheep("Jerry",2,"black");

Sheep sheep1 = (Sheep) sheep.clone();

演示图如下:

在这里插入图片描述

深拷贝: 也是原类对象需实现Cloneable接口,并且覆写clone()方法实现对引用数据类型的拷贝功能,实现开辟所有数据类型所需的地址空间,从而实现深拷贝,两个对象完全不等。

​ 如:此时的clone方法已经覆写,下面会有具体覆写过程哦!

Sheep sheep = new Sheep("tom",1,"white");
sheep.sheepFriends = new Sheep("Jerry",2,"black");

Sheep sheep1 = (Sheep) sheep.clone();

演示图如下:

在这里插入图片描述

那么它们具体怎样实现和使用呢,让我们通过具体的一些案例来演示一下吧,嘻嘻~

具体案例演示

对象的引用传递

Sheep类

package com.design_patterns.prototype.instance;

public class Sheep {
    
    
    private String name;
    private int age;
    private String color;

    public Sheep(String name, int age, String color) {
    
    
        this.name = name;
        this.age = age;
        this.color = color;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getColor() {
    
    
        return color;
    }

    public void setColor(String color) {
    
    
        this.color = color;
    }

    @Override
    public String toString() {
    
    
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

测试类

package com.design_patterns.prototype.instance;


public class Client {
    
    
    public static void main(String[] args) {
    
    
        Sheep sheep = new Sheep("tom",1,"white");

        Sheep sheep1 = sheep;
        System.out.println(sheep + "\n" + sheep.hashCode() + "\n");
        System.out.println(sheep1 + "\n" + sheep1.hashCode() + "\n");
        System.out.println("这两个对象是否相等?" + (sheep == sheep1));
    }
}

运行结果

Sheep{
    
    name='tom', age=1, color='white'}
1163157884

Sheep{
    
    name='tom', age=1, color='white'}
1163157884

这两个对象是否相等?true

对象的浅拷贝

Sheep类

package com.design_patterns.prototype.improve;

public class Sheep implements Cloneable {
    
    
    private String name;
    private int age;
    private String color;
    public Sheep sheepFriends;

    public Sheep(String name, int age, String color) {
    
    
        this.name = name;
        this.age = age;
        this.color = color;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getColor() {
    
    
        return color;
    }

    public void setColor(String color) {
    
    
        this.color = color;
    }

    @Override
    public String toString() {
    
    
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }

    /**
     * 克隆该实例,使用默认的clone()方法完成
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        Sheep sheep = null;
        sheep = (Sheep)super.clone();
        return sheep;
    }
}

测试类

package com.design_patterns.prototype.improve;


public class Client {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        Sheep sheep = new Sheep("tom",1,"white");
        sheep.sheepFriends = new Sheep("Jerry",2,"black");

        Sheep sheep1 = (Sheep) sheep.clone();

        System.out.println("sheep---->" + sheep + "\nhashcode---->" + sheep.hashCode() + "\n"
                + sheep.sheepFriends.hashCode() + "\n" + sheep.sheepFriends + "\n");
        System.out.println("sheep1---->" + sheep1 + "\nhashcode---->" + sheep1.hashCode() + "\n"
                + sheep1.sheepFriends.hashCode() + "\n" + sheep1.sheepFriends + "\n");

        sheep.sheepFriends.setName("Jerry Hello");

        System.out.println("这两个对象是否相等?" + (sheep == sheep1));
        System.out.println("它们的属性对象是否为同一个对象?" + (sheep.sheepFriends == sheep1.sheepFriends));
    }
}

运行结果

sheep---->Sheep{
    
    name='tom', age=1, color='white'}
hashcode---->1163157884
1956725890
Sheep{
    
    name='Jerry', age=2, color='black'}

sheep1---->Sheep{
    
    name='tom', age=1, color='white'}
hashcode---->356573597
1956725890
Sheep{
    
    name='Jerry', age=2, color='black'}

这两个对象是否相等?false
它们的属性对象是否为同一个对象?true

对象的深拷贝(通过覆写clone()方法实现)

Sheep类

package com.design_patterns.prototype.deepclone;

import java.io.*;

public class Sheep implements Cloneable, Serializable {
    
    
    private String name;
    private int age;
    private String color;
    public Sheep sheepFriends;

    public Sheep(String name, int age, String color) {
    
    
        this.name = name;
        this.age = age;
        this.color = color;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getColor() {
    
    
        return color;
    }

    public void setColor(String color) {
    
    
        this.color = color;
    }

    @Override
    public String toString() {
    
    
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }


    /**
     * 覆写clone()方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        Object deep = null;
        //这里对基本数据类型属性的克隆
        deep = super.clone();
        //对应用数据类型的属性进行单独处理
        Sheep sheep = (Sheep)deep;
        if(this.sheepFriends != null){
    
                  //若引用数据类型不为空,也进行拷贝复制
            sheep.sheepFriends = (Sheep) this.sheepFriends.clone();
        }

        return sheep;
    }


    /**
     * 也是深拷贝方法,通过对对象对象实现序列化的操作完成对象的全部拷贝工作
     * 通常建议用此种方法实现对象的深拷贝,此类需要实现Serializable接口
     * @return
     */
    public Object deepClone(){
    
    
        Sheep sheep = null;

        //创建流对象
        ByteArrayOutputStream byteArrayOutputStream = null;             //定义内存输出流
        ObjectOutputStream objectOutputStream = null;                   //定义对象输出流
        ByteArrayInputStream byteArrayInputStream = null;           //定义内存输入流
        ObjectInputStream objectInputStream = null;                 //定义对象输入流

        try{
    
    
            byteArrayOutputStream = new ByteArrayOutputStream();                    //实例化内存输出流
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);       //实例化对象输出流,将对象输出到内存中
            objectOutputStream.writeObject(this);               //将对象写入内存


            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());   //实例化内存输入流
            objectInputStream = new ObjectInputStream(byteArrayInputStream);                //实例化对象输入流
            sheep = (Sheep)objectInputStream.readObject();                      //将此对象再读取出来,写入sheep对象中

            objectInputStream.close();
            byteArrayInputStream.close();
            objectOutputStream.close();
            byteArrayOutputStream.close();              //关闭流对象
        }catch (Exception e) {
    
    
            e.printStackTrace();
        }

        return sheep;           //返回深拷贝的对象
    }
}

测试类

package com.design_patterns.prototype.deepclone;


public class Client {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        Sheep sheep = new Sheep("tom",1,"white");
        sheep.sheepFriends = new Sheep("Jerry",2,"black");

        Sheep sheep1 = (Sheep) sheep.clone();                   //采用引用数据也克隆的方式
        Sheep sheep2 = (Sheep) sheep.deepClone();               //采用对象序列化的操作实现深拷贝



        System.out.println("sheep---->" + sheep + "\nhashcode---->" + sheep.hashCode() + "\n"
                + sheep.sheepFriends.hashCode() + "\n" + sheep.sheepFriends + "\n");
        System.out.println("sheep1---->" + sheep1 + "\nhashcode---->" + sheep1.hashCode() + "\n"
                + sheep1.sheepFriends.hashCode() + "\n" + sheep1.sheepFriends + "\n");
        System.out.println("sheep2---->" + sheep2 + "\nhashcode---->" + sheep2.hashCode() + "\n"
                + sheep2.sheepFriends.hashCode() + "\n" + sheep2.sheepFriends + "\n");

        System.out.println("这三个对象相同嘛(sheep、sheep1、sheep2):"+ "\n" + (sheep == sheep1)+ "\n" + (sheep == sheep2)
                + "\n" +(sheep1 == sheep2) + "\n");

        System.out.println("这三个对象的引用数据类型相同嘛:" + "\n" + (sheep.sheepFriends == sheep1.sheepFriends) + "\n" +
                (sheep.sheepFriends == sheep2.sheepFriends) + "\n"+ (sheep1.sheepFriends == sheep2.sheepFriends) + "\n");
    }
}

运行结果

sheep---->Sheep{
    
    name='tom', age=1, color='white'}
hashcode---->325040804
312714112
Sheep{
    
    name='Jerry', age=2, color='black'}

sheep1---->Sheep{
    
    name='tom', age=1, color='white'}
hashcode---->931919113
1607521710
Sheep{
    
    name='Jerry', age=2, color='black'}

sheep2---->Sheep{
    
    name='tom', age=1, color='white'}
hashcode---->764977973
381259350
Sheep{
    
    name='Jerry', age=2, color='black'}

这三个对象相同嘛(sheep、sheep1、sheep2)false
false
false

这三个对象的引用数据类型相同嘛:
false
false
false


总结

到此,这就是Java对象的引用传递、对象浅拷贝、对象深拷贝的全部区别,如果感觉这篇文章写的还不错(代码的冗余有点多,嘻嘻),帮忙点个赞哦,谢谢小伙伴们的支持~

猜你喜欢

转载自blog.csdn.net/weixin_43479947/article/details/107464863