java对象克隆和序列化

转载自http://www.cnblogs.com/rollenholt/archive/2011/09/09/2172094.html


先用一个例子来说明假克隆吧,也就是用“=”之后的效果、。

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
public  class  Employee{
     public  Employee(){
 
     }
 
     public  Employee(String name,  int  age){
         this .age = age;
         this .name = name;
     }
 
     @Override
     public  String toString(){
         return  "姓名: "  + name +  "年龄: "  + age;
     }
 
     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  static  void  main(String[] args){
         Employee demo1 =  new  Employee( "rollen" 20 );
         System.out.println(demo1);
         Employee demo2 = demo1;
         demo2.setAge( 100 );
         demo2.setName( "hello world" );
         System.out.println(demo1);
         System.out.println(demo2);
     }
 
     private  String name;
     private  int  age;
}

【运行结果】:

【运行结果】

姓名: rollen年龄: 20

姓名: hello world年龄: 100

姓名: hello world年龄: 100


下面看看java中的浅拷贝

对于类中的每个域,如果只包含基本类型或者不可变的引用类型,如String,或者对象在其生命周期内不会发生变化,则可以使用浅拷贝来复制对象,但是一般使用深拷贝。

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
class  Address{
     public  Address(){
 
     }
 
     public  Address(String state,  int  number){
         this .number = number;
         this .state = state;
     }
 
     @Override
     public  String toString(){
         return  "state: "  + state +  " munber: "  + number;
     }
 
     public  String getState(){
         return  state;
     }
 
     public  void  setState(String state){
         this .state = state;
     }
 
     public  int  getNumber(){
         return  number;
     }
 
     public  void  setNumber( int  number){
         this .number = number;
     }
 
     private  String state;
     private  int  number;
}
 
public  class  Employee  implements  Cloneable{
     public  Employee(){
 
     }
 
     public  Employee(String name,  int  age, Address address){
         this .address = address;
         this .age = age;
         this .name = name;
     }
 
     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  Address getAddress(){
         return  address;
     }
 
     public  void  setAddress(Address address){
         this .address = address;
     }
 
     @Override
     public  String toString(){
         StringBuilder sb =  new  StringBuilder();
         sb.append( "name:"  + name +  ", " );
         sb.append( "age:"  + age +  " \n" );
         sb.append( "Address: "  + address);
         return  sb.toString();
     }
 
     @Override
     protected  Employee clone(){
         Employee employee =  null ;
         try {
             employee = (Employee)  super .clone();
         } catch (CloneNotSupportedException e){
             e.printStackTrace();
         }
         return  employee;
     }
 
     public  static  void  main(String[] args){
         System.out.println( "克隆之前:" );
         Address add1 =  new  Address( "中国" 1 );
         Employee emp1 =  new  Employee( "rollen" 20 , add1);
         System.out.println(emp1);
         System.out.println( "克隆之后" );
         Employee emp2 = emp1.clone();
         emp2.setName( "hello world" );
         emp2.setAge( 100 );
         emp2.address.setNumber( 2 );
         emp2.address.setState( "美国" );
         System.out.println(emp1);
         System.out.println( "-----" );
         System.out.println(emp2);
     }
 
     private  String name;
     private  int  age;
     private  Address address;
}

【运行结果】:

克隆之前:

name:rollen, age:20

Address: state: 中国 munber: 1

克隆之后

name:rollen, age:20

Address: state: 美国 munber: 2

-----

name:hello world, age:100

Address: state: 美国 munber: 2

 

但是上面的主函数中的:

1
2
// emp2.address.setNumber(2);
// emp2.address.setState("美国");

替换为:

1
emp2.setAddress( new  Address( "美国" 2 ));

运行结果为:

克隆之前:

name:rollen, age:20

Address: number: 1state中国

 

克隆之后

name:rollen, age:20

Address: number: 1state中国

 

-----

name:hello world, age:100

Address: number: 2state美国

 

这里我有点不明白了,为什么这种情况下克隆之后两个address会不一样呢?

谁帮忙指点一下,谢谢了、

现在看看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
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class  Address  implements  Cloneable{
     public  Address(){
 
     }
 
     public  Address(String state,  int  number){
         this .number = number;
         this .state = state;
     }
 
     @Override
     public  String toString(){
         return  "state: "  + state +  " munber: "  + number;
     }
 
     @Override
     protected  Address clone()  throws  CloneNotSupportedException{
         Address address =  null ;
         address = (Address)  super .clone();
         return  address;
     }
 
     public  String getState(){
         return  state;
     }
 
     public  void  setState(String state){
         this .state = state;
     }
 
     public  int  getNumber(){
         return  number;
     }
 
     public  void  setNumber( int  number){
         this .number = number;
     }
 
     private  String state;
     private  int  number;
}
 
public  class  Employee  implements  Cloneable{
     public  Employee(){
 
     }
 
     public  Employee(String name,  int  age, Address address){
         this .address = address;
         this .age = age;
         this .name = name;
     }
 
     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  Address getAddress(){
         return  address;
     }
 
     public  void  setAddress(Address address){
         this .address = address;
     }
 
     @Override
     public  String toString(){
         StringBuilder sb =  new  StringBuilder();
         sb.append( "name:"  + name +  ", " );
         sb.append( "age:"  + age +  " \n" );
         sb.append( "Address: "  + address);
         return  sb.toString();
     }
 
     @Override
     protected  Employee clone(){
         Employee employee =  null ;
         try {
             employee = (Employee)  super .clone();
             employee.address = address.clone();     } catch (CloneNotSupportedException e){
             e.printStackTrace();
         }
         return  employee;
     }
 
     public  static  void  main(String[] args){
         System.out.println( "克隆之前:" );
         Address add1 =  new  Address( "中国" 1 );
         Employee emp1 =  new  Employee( "rollen" 20 , add1);
         System.out.println(emp1);
         System.out.println( "克隆之后" );
         Employee emp2 = emp1.clone();
         emp2.setName( "hello world" );
         emp2.setAge( 100 );
         emp2.setAddress( new  Address( "美国" 2 ));
         System.out.println(emp1);
         System.out.println( "-----" );
         System.out.println(emp2);
     }
 
     private  String name;
     private  int  age;
     private  Address address;
}

【运行结果】:

【运行结果】:

克隆之前:

name:rollen, age:20

Address: state: 中国 munber: 1

克隆之后

name:rollen, age:20

Address: state: 中国 munber: 1

-----

name:hello world, age:100

Address: state: 美国 munber: 2

序列化接口和对象克隆

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import  java.io.ByteArrayInputStream;
import  java.io.ByteArrayOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  java.io.Serializable;
 
class  Address  implements  Serializable{
     public  Address(){
 
     }
 
     public  Address(String state,  int  number){
         this .number = number;
         this .state = state;
     }
 
     @Override
     public  String toString(){
         StringBuilder sb =  new  StringBuilder();
         sb.append( "number: "  + number);
         sb.append( "state"  + state +  "\n" );
         return  sb.toString();
     }
 
     public  String getState(){
         return  state;
     }
 
     public  void  setState(String state){
         this .state = state;
     }
 
     public  int  getNumber(){
         return  number;
     }
 
     public  void  setNumber( int  number){
         this .number = number;
     }
 
     private  String state;
     private  int  number;
}
 
public  class  Employee  implements  Cloneable, Serializable{
     public  Employee(){
 
     }
 
     public  Employee(String name,  int  age, Address address){
         this .address = address;
         this .age = age;
         this .name = name;
     }
 
     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  Address getAddress(){
         return  address;
     }
 
     public  void  setAddress(Address address){
         this .address = address;
     }
 
     @Override
     public  String toString(){
         StringBuilder sb =  new  StringBuilder();
         sb.append( "name:"  + name +  ", " );
         sb.append( "age:"  + age +  " \n" );
         sb.append( "Address: "  + address);
         return  sb.toString();
     }
 
     @Override
     protected  Employee clone(){
         Employee employee =  null ;
         ByteArrayOutputStream baos =  new  ByteArrayOutputStream();
         try {
             ObjectOutputStream oos =  new  ObjectOutputStream(baos);
             oos.writeObject( this );
             oos.close();
 
             ByteArrayInputStream bais =  new  ByteArrayInputStream(
                     baos.toByteArray());
             ObjectInputStream ois =  new  ObjectInputStream(bais);
             employee = (Employee) ois.readObject();
             ois.close();
         } catch (Exception e){
             e.printStackTrace();
         }
         return  employee;
     }
 
     public  static  void  main(String[] args){
         System.out.println( "克隆之前:" );
         Address add1 =  new  Address( "中国" 1 );
         Employee emp1 =  new  Employee( "rollen" 20 , add1);
         System.out.println(emp1);
         System.out.println( "克隆之后" );
         Employee emp2 = emp1.clone();
 
         emp2.setName( "hello world" );
         emp2.setAge( 100 );
         emp2.address.setNumber( 2 );
         emp2.address.setState( "美国" );
         System.out.println(emp1);
         System.out.println( "-----" );
         System.out.println(emp2);
     }
 
     private  String name;
     private  int  age;
     private  Address address;
}

【运行结果】:

克隆之前:

name:rollen, age:20

Address: number: 1state中国

 

克隆之后

name:rollen, age:20

Address: number: 1state中国

 

-----

name:hello world, age:100

Address: number: 2state美国


 

对于任何一个序列化的对象,都必须要求实现Serializable接口。其次,如果这个类的域中也有引用对象,则也有要求这个引用类型也实现这个接口,。最后,序列化方式实现克隆效率不高,没有直接深度克隆的效率高。有兴趣的朋友 可以测试一下。





==============================================================================
我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他
们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其
实我是一个程序员
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值