`

JAVA 对象克隆和序列化

    博客分类:
  • 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
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接口。其次,如果这个类的域中也有引用对象,则也有要求这个引用类型也实现这个接口,。最后,序列化方式实现克隆效率不高,没有直接深度克隆的效率高。有兴趣的朋友 可以测试一下。

 

分享到:
评论

相关推荐

    基于序列化存取实现java对象深度克隆的方法详解

    本篇文章是对序列化存取实现java对象深度克隆的方法进行了详细的分析介绍,需要的朋友参考下

    Java中对象的序列化方式克隆详解

    在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走...这篇文章主要给大家介绍了Java中对象的序列化方式克隆,需要的朋友可以参考借鉴,下面来一起看看吧。

    一款轻量级Java对象高效克隆框架,提供高性能的深克隆(非对象->序列化->对象这种低效率克隆)、浅克隆,支持分区克隆

    示例Bean.java 公共类ExampleBean { 私有 int id; 私人用户用户; 私人名单名单; 公共 int getId() { 返回ID; } 公共无效setId(int id){ 这个.id = id; } 公共用户 getUser() { 返回用户; } ...

    KryoJava序列化和克隆框架具有快速高效自动的特点

    Kryo - 针对Java的快速和高效对象图序列化框架

    Java利用序列化实现对象深度clone的方法

    主要介绍了Java利用序列化实现对象深度clone的方法,实例分析了java序列化及对象克隆的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    JDSer-ngng:Burp Extender 插件,它将反序列化 java 对象并使用 Xtream 库将它们编码为 XML

    将“send deserialized to intruder”的输出复制并粘贴到一个文件中,以及 sqlmap.py -r --proxy " " 基本上,它将反序列化、修改、重新序列化、发送和(仅在扫描器的情况下)反序列化任何看起来像 Java 对象的响应...

    JAVA核心知识点整理.zip

    java核心知识点整理,面试很有用 Java核心知识点2.JVM JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个...5.6JAVA 序列化(创建可复用的 Java 对象) 5.7JAVA 复制 6. Spring 原理

    《剑指offer》Java创建对象的五种方式.pdf

    Java 创建对象的五种方式 使用 new 来创建对象 使用 newInstance 方法来创建 使用反射来创建对象 使用对象克隆来创建对象 使用反序列化创建对象

    kryo:Java二进制序列化和克隆:快速,高效,自动

    Kryo是用于Java的快速高效的二进制对象图序列化框架。 该项目的目标是高速,小尺寸和易于使用的API。 每当需要将对象持久保存到文件,数据库还是通过网络时,该项目都是有用的。 Kryo还可以执行自动的深层和浅层...

    JavaEE技术问题汇总.docx

    序列化和反序列化使用的API 如何实现Java中的一个对象中某一个属性不被序列化,如何实现呢? Java中堆内存和栈内存区别 讲一讲反射,主要是概念,都在哪需要反射机制 JSP中有个概念,静态包含和动态包含? ...

    java源码包---java 源码 大量 实例

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    Java开发技术大全(500个源代码).

    ObjectFileTest.java 序列化对象示例 ReadAndWrite.java 读入和写出数据 ReadAndWriteFile.java 读入数据写出到文件 Student.java 定义一个用来序列化的类 ThreadIn.java 接收数据用的线程类 ThreadOut.java ...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java jdk实列宝典 光盘源代码

    序列化和反序列化对象(将不长用的对象暂时持久化到文件中为对象的序列化,反之用时再把对象恢复到内存为反序列化); 控制对象的序列化和反序列化; 读jar包的资源文件;用zip格式压缩 和解压文件;操作Excel文件;...

    java源码包4

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java 编程入门思考

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    java源码包3

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    Java初学者入门教学

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

Global site tag (gtag.js) - Google Analytics