clone() 浅拷贝与深拷贝

clone的用法

用来复制一个对象的副本,产生一个新的对象,新对象的属性与原对象的属性一致,而且原对象的改变不影响新对象

克隆有浅拷贝与深拷贝,用的时候一定要注意

使用对象的clone()方法时,需要实现Cloneable接口,这是一个标志接口,不提供任何抽象方法

1
2
public interface Cloneable {
}

浅拷贝

先来看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Persion implements Cloneable{

private int age;
private String name;

public Persion(int age, String name) {

this.age = age;
this.name = name;
}

@Override
protected Object clone() throws CloneNotSupportedException {

return super.clone();
}

public static void main(String[] args) throws CloneNotSupportedException {

Persion p = new Persion(18,"zhang");
Persion p2 = (Persion) p.clone();
System.out.println(p.name == p2.name);
}
}

它的打印结果是什么呢?

true

没看错,就是这个结果,有没有困惑的地方?这就是由于浅拷贝导致的。看张图:

由于name是String类型,拷贝的只是它的引用,所以他们的name的地址值是相等的

那怎样将它改为深拷贝呢?

如果是引用类型,我们需要重新在原对象的基础上重新创建出一个对象。

例如,将上面改为深拷贝,只需要修改一下clone方法

1
2
3
4
5
6
7
8
@Override
protected Object clone() throws CloneNotSupportedException {

String newName = new String(this.name);//拷贝原对象的name值
Persion p = (Persion)super.clone();
p.name = newName;
return p;
}

深拷贝

再来看一个深拷贝的例子:

A要实现深拷贝,必须要求其属性中含有的引用类型也必须进行深拷贝,也就是要求B要进行深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class A implements Cloneable{

int id;
B b;

public A(int id, B b) {

this.id = id;
this.b = b;
}

@Override
protected Object clone() throws CloneNotSupportedException {
//深拷贝
B nb = (B) b.clone();
A na = (A) super.clone();
na.b = nb;

return na;
}
}

class B implements Cloneable {

String name;
B(String name) {

this.name = name;
}

@Override
protected Object clone() throws CloneNotSupportedException {

B b = (B) super.clone();
String sname = new String(name);
b.name = sname;
return b;
}
}
文章目录
  1. 1. clone的用法
  2. 2. 浅拷贝
  3. 3. 深拷贝
|
载入天数...载入时分秒...