Java专题十九:浅拷贝与深拷贝
Posted 黄先生的日志
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java专题十九:浅拷贝与深拷贝相关的知识,希望对你有一定的参考价值。
Java专题十九:浅拷贝与深拷贝
目录
19.1. clone方法
clone
方法是Object
类提供的一个用于对象拷贝的方法,且是protected
,使用时需要类实现java.lang.Cloneable
接口,否则将抛出CloneNotSupportedException
异常
// java.lang.Object
protected native Object clone() throws CloneNotSupportedException;
使用clone
通常遵循的约定:
x.clone() != x
返回turex.clone().getClass() == x.getClass()
返回turex.clone().equals(x)
返回ture
19.2. 浅拷贝
- 对于基本数据类型字段,直接赋值给新的对象
- 对于引用数据类型字段,复制对象引用(对象地址)到新的对象
- 问题:对新对象中引用数据类型字段的修改会一同修改源对象引用数据类型字段,因为两个字段引用的是同一个对象地址
19.3. 深拷贝
- 对于基本数据类型字段,直接赋值给新的对象
- 对于引用数据类型字段,为字段构造一个新的对象,并将源对象字段中每一个子字段赋值到新的对象字段中
假设有一个Person
类,有眼睛(eye
字段)和性别(sex
字段),其中sex
是基本数据类型,eye
是引用数据类型
public class Person{
public static final int SEX_MAN = 0;
public static final int SEX_WOMAN = 0;
private int sex;
private Eye eye;
public Person shallowCopy(){
Person dest = new Person();
dest.sex = this.sex;
dest.eye = this.eye;
return dest;
}
public Person deepCopy(){
Person dest = new Person();
dest.sex = this.sex;
dest.eye = this.eye.deepCopy();
return dest;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName() + "@" + Integer.toHexString(hashCode()))
.append(": { ")
.append("sex: ").append(sex).append(", ")
.append("eye: ").append(eye.toString())
.append(" }");
return buffer.toString();
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public Eye getEye() {
return eye;
}
public void setEye(Eye eye) {
this.eye = eye;
}
}
class Eye {
public static final String COLOR_BLACK = "black";
public static final String COLOR_BLUE = "blue";
private String color;
private int size;
public Eye(String color, int size){
this.color = color;
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Eye deepCopy(){
return new Eye(this.color, this.size);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName() + "@" + Integer.toHexString(hashCode()))
.append(": { ")
.append("color: ").append(color).append(", ")
.append("size: ").append(size)
.append(" }");
return buffer.toString();
}
}
19.4. 实现方法
19.4.1. 浅拷贝
19.4.1.1. 使用shalldowCopy方法
shalldowCopy为自定义的方法,在方法中,直接构造一个新对象,将源对象的每一个字段使用=
赋值给新对象中,调用shalldowCopy()方法即可完成浅拷贝
19.4.1.2. 使用clone方法
重写clone
方法,在类的clone
方法种直接调用super.clone()
,调用clone()方法即可完成浅拷贝
public class Person implements Cloneable {
public Person clone(){
Person dest = null;
try{
dest = (Person) super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return dest;
}
}
19.4.2. 深拷贝
19.4.2.1. 使用deepCopy方法
deepCopy为自定义的方法,在方法中,直接构造一个新对象,对源对象的基本数据类型字段使用=
赋值给新对象中,对于引用数据类型使用deepCopy方法赋值,调用deepCopy()方法即可完成深拷贝
19.4.2.2. 使用clone方法
重写clone
方法,在类的clone
方法种调用super.clone()
,对于引用数据类型使用deepCopy方法赋值,调用clone()方法即可完成深拷贝
public class Person implements Cloneable {
public Person clone(){
Person dest = null;
try{
dest = (Person) super.clone();
dest.eye = dest.eye.deepCopy();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return dest;
}
}
以上是关于Java专题十九:浅拷贝与深拷贝的主要内容,如果未能解决你的问题,请参考以下文章