1 实体
1.0 浅拷贝实体
package com.company.common;
import java.io.Serializable;
/**
* 用户信息实体
* @author xindaqi
* @since 2020-12-19
*/
public class UserInformationEntity implements Serializable, Cloneable {
// private static final long serialVersionUID = 1547123013328323240L;
public String nickname;
private String address;
private FamilyInformationEntity familyInformationEntity;
public FamilyInformationEntity getFamilyInformationEntity() {
return familyInformationEntity;
}
public void setFamilyInformationEntity(FamilyInformationEntity familyInformationEntity) {
this.familyInformationEntity = familyInformationEntity;
}
public UserInformationEntity() {}
public UserInformationEntity(String nickname, String address) {
this.nickname = nickname;
this.address = address;
}
public UserInformationEntity(String nickname, String address, FamilyInformationEntity familyInformationEntity) {
this.nickname = nickname;
this.address = address;
this.familyInformationEntity = familyInformationEntity;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
}
1.2 深拷贝实体
package com.company.common;
/**
* 深拷贝对象
* @author xindaqi
* @since 2020-12-20
*/
public class UserInformationDeepEntity implements Cloneable {
public String nickname;
private String address;
private FamilyInformationEntity familyInformationEntity;
public FamilyInformationEntity getFamilyInformationEntity() {
return familyInformationEntity;
}
public void setFamilyInformationEntity(FamilyInformationEntity familyInformationEntity) {
this.familyInformationEntity = familyInformationEntity;
}
public UserInformationDeepEntity() {}
public UserInformationDeepEntity(String nickname, String address) {
this.nickname = nickname;
this.address = address;
}
public UserInformationDeepEntity(String nickname, String address, FamilyInformationEntity familyInformationEntity) {
this.nickname = nickname;
this.address = address;
this.familyInformationEntity = familyInformationEntity;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException {
// 获取User对象
UserInformationDeepEntity userInformationDeepEntity = (UserInformationDeepEntity) super.clone();
/**
* Family对象拷贝至User的Family对象
* 在新开辟的堆空间,重新设置Family对象的值
*/
userInformationDeepEntity.setFamilyInformationEntity((FamilyInformationEntity) userInformationDeepEntity.getFamilyInformationEntity().clone());
return userInformationDeepEntity;
}
}
1.3 引用实体
package com.company.common;
/**
* 家庭信息实体
* @author xindaqi
* @since 2020-12-20
*/
public class FamilyInformationEntity implements Cloneable {
private String address;
private Integer memberCount;
public FamilyInformationEntity() {}
public FamilyInformationEntity(String address, Integer memberCount) {
this.address = address;
this.memberCount = memberCount;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getMemberCount() {
return memberCount;
}
public void setMemberCount(Integer memberCount) {
this.memberCount = memberCount;
}
@Override
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
}
2 引用拷贝(克隆)
package com.company.clone;
import com.company.common.UserInformationEntity;
/**
* 拷贝
* @author xindaqi
* @since 2020-12-20
*/
public class ShallowClone {
public static void main(String[] args) {
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江");
UserInformationEntity referenceObject = userInformationEntity;
System.out.println("原对象: " + userInformationEntity);
System.out.println("引用对象:" + referenceObject);
try {
UserInformationEntity copyObject = (UserInformationEntity) userInformationEntity.clone();
System.out.println("拷贝对象:" + copyObject);
} catch(Exception e) {
e.printStackTrace();
}
}
}
- 结果
原对象: com.company.common.UserInformationEntity@6e0be858
引用对象:com.company.common.UserInformationEntity@6e0be858
拷贝对象:com.company.common.UserInformationEntity@61bbe9ba
- 堆结果
由图1.0可知,原对象和引用拷贝对象的地址相同,均指向同一个地址@512,原对象和拷贝对象的地址不同,说明,拷贝对象新建了一个新的对象,开辟新型的堆内存@513。
3 浅拷贝(克隆)
只为第一级属性开辟堆空间,共用引用类(嵌套类)属性,即新建的对象只限于第一层属性,不会穿透其他对象。
package com.company.clone;
import com.company.common.FamilyInformationEntity;
import com.company.common.UserInformationEntity;
/**
* 浅克隆
* @author xindaqi
* @since 2020-12-20
*/
public class ShallowClone {
public static void main(String[] args) {
FamilyInformationEntity familyInformationEntity = new FamilyInformationEntity("黑龙江", 3);
UserInformationEntity userInformationEntity = new UserInformationEntity("xiaoxiao", "黑龙江", familyInformationEntity);
System.out.println("原对象: " + userInformationEntity);
try {
UserInformationEntity shallowCopyObject = (UserInformationEntity) userInformationEntity.clone();
System.out.println("浅拷贝对象:" + shallowCopyObject);
} catch(Exception e) {
e.printStackTrace();
}
}
}
- 结果如图
由图2.1可知,User实体中包含Family实体(引用类)地址分配如下表,User类内的Famliy堆地址为511,而浅拷贝的对象shallow中的family对象地址仍为511,说明浅拷贝只为原对象第一级属性开辟了内存空间,与原对象共用引用的对象。
序号 | 对象 | 堆地址 |
---|---|---|
1 | user | 508 |
2 | family | 511 |
3 | shallowCopyObject | 512 |
4 深拷贝(拷贝)
为所有属性开辟堆空间,即穿透所有引用的类。
package com.company.clone;
import com.company.common.FamilyInformationEntity;
import com.company.common.UserInformationDeepEntity;
import com.company.common.UserInformationEntity;
/**
* 深拷贝
* @author xindaqi
* @since 2020-12-20
*/
public class DeepClone {
public static void main(String[] args) {
FamilyInformationEntity familyInformationEntity = new FamilyInformationEntity("黑龙江", 3);
UserInformationDeepEntity userInformationDeepEntity = new UserInformationDeepEntity("xiaoxiao", "黑龙江", familyInformationEntity);
System.out.println("原对象: " + userInformationDeepEntity);
try {
UserInformationDeepEntity deepCopyObject = (UserInformationDeepEntity) userInformationDeepEntity.clone();
System.out.println("深拷贝对象:" + deepCopyObject);
} catch(Exception e) {
e.printStackTrace();
}
}
}
- 结果
由图3.1可知,User实体中包含Family实体(引用类)地址分配如下表,User类内的Famliy堆地址为511,深拷贝的对象deep中的family对象地址为516,说明深拷贝为所有的属性开辟堆空间。
5 小结
- 引用:共用堆空间
- 对象拷贝:开辟新的堆空间
- 浅拷贝和浅拷贝均为对象拷贝,为属性开辟新的堆空间
- 浅拷贝:只为一级属性开辟新的堆空间,共用应用的类所处的堆空间,不进行穿透开辟
- 深拷贝:为所有属性开辟新的堆空间
【参考文献】
[1]https://blog.youkuaiyun.com/lcsy000/article/details/82782864
[2]https://blog.youkuaiyun.com/riemann_/article/details/87217229