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、付费专栏及课程。

余额充值