有两种方式:
1). 实现Cloneable接口并重写Object类中的clone()方法;
2). 实现Serializable接口,经过对象的序列化和反序列化实现克隆,能够实现真正的深度克隆,代码以下。java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import
java.io.ByteArrayInputStream;
import
java.io.ByteArrayOutputStream;
import
java.io.ObjectInputStream;
import
java.io.ObjectOutputStream;
public
class
MyUtil {
private
MyUtil() {
throw
new
AssertionError();
}
public
static
<T> T clone(T obj)
throws
Exception {
ByteArrayOutputStream bout =
new
ByteArrayOutputStream();
ObjectOutputStream oos =
new
ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin =
new
ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois =
new
ObjectInputStream(bin);
return
(T) ois.readObject();
// 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
// 这两个基于内存的流只要垃圾回收器清理对象就可以释放资源,这一点不一样于对外部资源(如文件流)的释放
}
}
|
下面是测试代码:ide
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
40
41
42
43
44
45
46
47
48
49
50
|
import
java.io.Serializable;
/**
* 人类
* @author
*
*/
class
Person
implements
Serializable {
private
static
final
long
serialVersionUID = -9102017020286042305L;
private
String name;
// 姓名
private
int
age;
// 年龄
private
Car car;
// 座驾
public
Person(String name,
int
age, Car car) {
this
.name = name;
this
.age = age;
this
.car = car;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
public
Car getCar() {
return
car;
}
public
void
setCar(Car car) {
this
.car = car;
}
@Override
public
String toString() {
return
"Person [name="
+ name +
", age="
+ age +
", car="
+ car +
"]"
;
}
}
|
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
|
/**
* 小汽车类
* @author
*
*/
class
Car
implements
Serializable {
private
static
final
long
serialVersionUID = -5713945027627603702L;
private
String brand;
// 品牌
private
int
maxSpeed;
// 最高时速
public
Car(String brand,
int
maxSpeed) {
this
.brand = brand;
this
.maxSpeed = maxSpeed;
}
public
String getBrand() {
return
brand;
}
public
void
setBrand(String brand) {
this
.brand = brand;
}
public
int
getMaxSpeed() {
return
maxSpeed;
}
public
void
setMaxSpeed(
int
maxSpeed) {
this
.maxSpeed = maxSpeed;
}
@Override
public
String toString() {
return
"Car [brand="
+ brand +
", maxSpeed="
+ maxSpeed +
"]"
;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
CloneTest {
public
static
void
main(String[] args) {
try
{
Person p1 =
new
Person(
"Hao LUO"
,
33
,
new
Car(
"Benz"
,
300
));
Person p2 = MyUtil.clone(p1);
// 深度克隆
p2.getCar().setBrand(
"BYD"
);
// 修改克隆的Person对象p2关联的汽车对象的品牌属性
// 原来的Person对象p1关联的汽车不会受到任何影响
// 由于在克隆Person对象时其关联的汽车对象也被克隆了
System.out.println(p1);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|