5-1-10-6-9-3-2-9-8-7
9-3-2-9-8-7
java中,如果我要拷贝(复制)一个对象该怎么做呢?今天就和大家一起看看Java中的拷贝。
首先要了解一下Java
中的数据类型,主要有两类:
基本类型
。也就是八大数据类型:byte,short,int,long,char,float,double,boolean
。基本数据类型在声明时,系统就给它分配数据空间,无论是否赋值。
引用类型
。
包括 类,接口和数组 。引用类型在声明时只是给变量分配了引用空间,并不分配数据空间。好了,了解了基础知识后,开始今天的拷贝问题。拷贝是什么呢?是用等号就可以完成的操作吗?看个例子:
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吗?
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
方法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
方法就可以完成对象的拷贝(浅拷贝)了
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类增加一个对象变量
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;
}
}
然后再去进行一个拷贝(浅拷贝)
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
对象的所有值,使得两个对象完全不影响。所以继续看看怎么实现深拷贝
。
深拷贝就是要把对象里面所有对象也进行拷贝,完整整个对象的真正拷贝,直接上代码
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
感谢大家的阅读,有一起学习的小伙伴可以关注下公众号—
码上积木
❤️ 每日三问知识点/面试题,积少成多。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有