前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >我要拷贝你—Java对象

我要拷贝你—Java对象

作者头像
码上积木
发布于 2020-12-25 02:04:51
发布于 2020-12-25 02:04:51
48100
代码可运行
举报
文章被收录于专栏:码上积木码上积木
运行总次数:0
代码可运行
上期答案

5-1-10-6-9-3-2-9-8-7

9-3-2-9-8-7

  • 先初始化父类(静态方法,代码块):5,1
  • 然后初始化子类 (静态方法,代码块):10,6
  • super()(父类非静态变量,父类的非静态代码块,父类的构造方法):9,3,2
  • 实例化子类(非静态变量,非静态代码块,构造方法):9,8,7

前言

java中,如果我要拷贝(复制)一个对象该怎么做呢?今天就和大家一起看看Java中的拷贝。

基础知识—数据类型

首先要了解一下Java中的数据类型,主要有两类:

  • 基本类型

也就是八大数据类型:byte,short,int,long,char,float,double,boolean。基本数据类型在声明时,系统就给它分配数据空间,无论是否赋值。

  • 引用类型。 包括 类,接口和数组 。引用类型在声明时只是给变量分配了引用空间,并不分配数据空间。

相等就是拷贝吗?

好了,了解了基础知识后,开始今天的拷贝问题。拷贝是什么呢?是用等号就可以完成的操作吗?看个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class User {
    private int age;

    public int getAge() {
        return age;
    }

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

定义usera的年龄为20,userb=usera,那么userb是拷贝了usera吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void main {
         User usera = new User();
         usera.setAge(20);
         User userb = usera;
         //修改usera的年龄
         usera.setAge(22);
         //输出userb的年龄,会发现也是22
         Log.e("", userb.getAge() + "");
}

我们可以发现,其实=并不是拷贝了对象,而是直接使用了usera对象的引用地址,也就是说usera和userb其实是一个人,没有拷贝。

那么,怎么拷贝呢?

浅拷贝

两步,完成对象的拷贝(浅拷贝)

  • 实现Cloneable接口
  • 重写clone方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class User2 implements Cloneable {
        private int age;
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        @NonNull
        @Override
        public Object clone() {
            User2 user2 = null;
            try {
                user2 = (User2) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return user2;
        }
    }

然后再调用clone方法就可以完成对象的拷贝(浅拷贝)了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void main() {
       User2 usera = new User2();
       usera.setAge(20);
       User2 userb = (User2) usera.clone();
       //修改usera的年龄
       usera.setAge(22);
       //输出userb的年龄,还是11
       Log.e("", userb.getAge() + "");
}

ok,至此完成了对象的拷贝(浅拷贝)了。大家估计也发现了,我在每个拷贝后面都加了一个 「(浅拷贝)」,拷贝为啥还分深浅呢?下面看一个案例

给user类增加一个对象变量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Favorite {
        private String sport;
        private String color;
        public String getSport() {
            return sport;
        }
        public void setSport(String sport) {
            this.sport = sport;
        }
        public String getColor() {
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
    }

    public class User3 implements Cloneable {
        private int age;
        private Favorite favorite;

        public Favorite getFavorite() {
            return favorite;
        }

        public void setFavorite(Favorite favorite) {
            this.favorite = favorite;
        }

        public int getAge() {
            return age;
        }

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

        @NonNull
        @Override
        public Object clone() {
            User3 user2 = null;
            try {
                user2 = (User3) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return user2;
        }
    }

然后再去进行一个拷贝(浅拷贝)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void main(String[] args) {
        User3 usera = new User3();
        Favorite favorite = new Favorite();
        favorite.setColor("蓝色");
        usera.setAge(20);
        usera.setFavorite(favorite);
        User3 userb = (User3) usera.clone();
        //修改usera的年龄和爱好颜色
        usera.setAge(22);
        usera.getFavorite().setColor("红色");
        //输出userb的年龄,还是11
        Log.e("", userb.getAge() + "");
        //输出userb的爱好,变成了红色!!
        Log.e("", userb.getFavorite().getColor() + "");
    }

这里我们发现,拷贝之后,年龄确实没变化,但是favorite 却跟着变了?所以,大概了解了:

  • 浅拷贝意思就是只拷贝对象中的基本数据类型,而引用数据类型还是引用传递,没有创建一个新的对象, 其实就是值传递+引用传递
  • 深拷贝呢就是对其中的引用数据类型进行拷贝的时候,创建了一个新的对象,并完全复制了其内的成员变量,简单点说,深拷贝就是可以copy对象的所有值,使得两个对象完全不影响。

所以继续看看怎么实现深拷贝

深拷贝

深拷贝就是要把对象里面所有对象也进行拷贝,完整整个对象的真正拷贝,直接上代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Favorite2 implements Cloneable {
        private String sport;
        private String color;

        public String getSport() {
            return sport;
        }

        public void setSport(String sport) {
            this.sport = sport;
        }

        public String getColor() {
            return color;
        }

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

        @Override
        public Object clone() {
            Favorite2 addr = null;
            try {
                addr = (Favorite2) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return addr;
        }
    }

    public class User4 implements Cloneable {
        private int age;
        private Favorite2 favorite;

        public Favorite2 getFavorite() {
            return favorite;
        }

        public void setFavorite(Favorite2 favorite) {
            this.favorite = favorite;
        }

        public int getAge() {
            return age;
        }

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

        @NonNull
        @Override
        public Object clone() {
            User4 user4 = null;
            try {
                user4 = (User4) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            user4.favorite = (Favorite2) favorite.clone();
            return user4;
        }
    }

    public class copyObject3 {
        public void main(String[] args) {
            User4 usera = new User4();
            Favorite2 favorite = new Favorite2();
            favorite.setColor("蓝色");
            usera.setAge(20);
            usera.setFavorite(favorite);
            User4 userb = (User4) usera.clone();
            //修改usera的年龄和爱好颜色
            usera.setAge(22);
            usera.getFavorite().setColor("红色");
            //输出userb的年龄,还是11
            Log.e("", userb.getAge() + "");
            //输出userb的爱好,还是蓝色
            Log.e("", userb.getFavorite().getColor() + "");
        }
    }

这样不仅是实体类里面的普通变量,还有对象变量全部都被拷贝一份出来了,也就完成了深拷贝。

总结

  • 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
  • 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

思考

今天也留一个思考题吧:

Kotlin中数据类有个方法可以完成拷贝,你知道是什么吗?这个方法是深拷贝还是浅拷贝呢?

参考

https://www.cnblogs.com/lmj612/p/10874052.html

感谢大家的阅读,有一起学习的小伙伴可以关注下公众号—码上积木❤️ 每日三问知识点/面试题,积少成多。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深拷贝的实现方式
复制对象后,如果修改了原对象或新对象的数据,造成了对其他对象的数据也同时发生了变化的现象,就是浅拷贝;对象之间仍然存在关联。
头发还在
2022/11/13
3950
Java对象拷贝
通过Object的clone方法实现浅拷贝,通过实现cloneable接口实现拷贝。
Java开发者之家
2021/06/17
5090
Java 浅拷贝和深拷贝
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去。
用户3467126
2019/09/04
6770
Java 浅拷贝和深拷贝
java浅拷贝和深拷贝(基础也是很重要的)
对于的github基础代码https://github.com/chywx/JavaSE
陈灬大灬海
2018/09/12
3650
java浅拷贝和深拷贝(基础也是很重要的)
漫画:什么是 “原型模式” ?
假如有一天,小灰被外星人抓走了,外星人要拿小灰做实验,想了解小灰在吃得好、睡得好、玩得开心的场景下,与现实中小灰的生存状态有什么区别。
小灰
2021/07/13
3350
关于Java的拷贝你能说出个123么?
java赋值是复制「对象引用」,如果我们想要得到一个对象的==副本==,使用赋值操作是无法达到目的的:修改新对象的值会同时修改旧对象的值。
sowhat1412
2020/12/02
3080
关于Java的拷贝你能说出个123么?
面试官:Java深拷贝和浅拷贝区别
结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherteacher的只是引用而已,他们都指向了一个相同的对象Teacher(“Taylor”,26)。这就叫做引用拷贝。
TimeFriends
2022/08/01
2440
图解Java设计模式之原型模式
现在有一只羊tom,姓名为 : tom,年龄为 :1,颜色为 :白色,请编写程序创建和tom羊属性完全相同的10只羊。
海仔
2020/03/19
4740
图解Java设计模式之原型模式
Java设计模式之原型模式
现在有一只羊,姓名为:tom,年龄为:1,颜色为:白色,请编写程序创建和tom羊属性完全相同的10只羊。
shaoshaossm
2022/12/27
2250
浅拷贝和深拷贝的方法java_jdg粗中有细
结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherteacher的只是引用而已,他们都指向了一个相同的对象Teacher(“Taylor”,26)。 这就叫做引用拷贝。
全栈程序员站长
2022/11/15
2540
浅拷贝和深拷贝的方法java_jdg粗中有细
一篇文章带你了解设计模式之原型模式
现在有一只羊tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和tom羊 属性完全相同的10只羊
@派大星
2023/06/28
1330
一篇文章带你了解设计模式之原型模式
Java深入理解深拷贝和浅拷贝区别
结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherTeacher的只是引用而已,他们都指向了一个相同的对象Teacher(“riemann”,28)。 这就叫做引用拷贝。
全栈程序员站长
2022/11/10
2020
Java深入理解深拷贝和浅拷贝区别
《23种设计模式(Java版)》| 原型模式(内附源码案例)。
原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建——来源于百度百科。
百思不得小赵
2022/12/01
2280
《23种设计模式(Java版)》| 原型模式(内附源码案例)。
一文了解Java对象的克隆,深浅拷贝(克隆)
在Java的Object类中,有一个方法名为clone(),直译过来就是克隆,核心概念就是复制对象并返回一个新的对象。
程序员小强
2020/05/14
3.4K0
Java漫谈-深拷贝与浅拷贝
2、运用反射手段创建对象,调用java.lang.Class 或者 java.lang.reflect.Constructor 类的newInstance()实例方
WindCoder
2018/09/19
3.2K0
【设计模式】-创建型模式-第2章第4讲-【原型模式】
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
跟着飞哥学编程
2022/12/02
3490
深拷贝与浅拷贝的区别?
浅拷贝(Shallow Copy):仅拷贝对象的非对象属性(基本类型属性)、不可变对象属性,但是不拷贝对象的对象属性(不含不可变对象) ,即为浅拷贝。
黑洞代码
2021/01/14
3790
深拷贝与浅拷贝的区别?
Java对象实现克隆的三种方式
Java 提供了 Cloneable 接口和 clone() 方法,用于支持对象克隆。在实现克隆时,需要满足以下条件:
IT可乐
2023/04/18
5.2K0
深/浅拷贝
在MyBaby类中有一个私有变量list,类似为List,然后咱们使用setValue对其进行设值,使用getValue进行取值。接下来咱们来看看他是如何拷贝的。
田维常
2019/07/16
4980
深/浅拷贝
【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )
1 . 原型模式本质及性能 : 原型模式使用 clone 方法克隆对象 , 其本质是在内存中拷贝二进制数据 , 这种方式要比调用 new 构造函数性能高得多 ;
韩曙亮
2023/03/27
2200
相关推荐
深拷贝的实现方式
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验