【总结】Java序列化,反序列化实例(属性类不实现序列化接口)

  1. 云栖社区>
  2. 博客>
  3. 正文

【总结】Java序列化,反序列化实例(属性类不实现序列化接口)

技术小胖子 2017-11-01 13:01:00 浏览874
展开阅读全文

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

Java中String, Integer的父类都实现了序列化接口


Person类实现了序列化接口,Person中的所有属性也必须实现序列化接口,

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
package serialize;
import java.io.Serializable;
 
/**
 * <p>ClassName: Person<p>
 * <p>Description:测试对象序列化和反序列化<p>
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 */
public class Person implements Serializable {
 
    /**
     * 序列化ID
     */
    private static final long serialVersionUID = -5809782578272943999L;
    private String name;
    private Pet pet;
     
    public Person(String name, String sex, int age, Pet pet) {
        this.name = name;
        this.pet = pet;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Pet getPet() {
        return pet;
    }
 
    public void setPet(Pet pet) {
        this.pet = pet;
    }
}

Pet类,也是Person中的一个属性,此处Pet没有实现Serializable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package serialize;
/**
 
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 *
 */
class Pet{
    private String name;
    public Pet(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return this.name;
    }
}

测试类

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
package serialize;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * <p>ClassName: TestSerializeAndDeserialize<p>
 * <p>Description: 测试对象的序列化和反序列<p>
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 */
public class TestSerializeAndDeserialize {
    private static Logger logger = LoggerFactory.getLogger(TestSerializeAndDeserialize.class);
     
    public static void main(String[] args) throws Exception {
        serializePerson();//序列化Person对象
        Person p = deserializePerson();//反序列Perons对象
        logger.info("name={},pet={}", p.getName(),p.getPet().toString());
    }
     
    private static void serializePerson() throws FileNotFoundException,
            IOException {
        Person person = new Person("qiaokeli""男"25new Pet("旺财"));
         
        //ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("E:/Person.txt")));
        oo.writeObject(person);
        logger.info("将Person序列化到文件");
        oo.close();
    }
    private static Person deserializePerson() throws Exception, IOException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:/Person.txt")));
        Person person = (Person) ois.readObject();
        logger.info("反序列化Person对象");
        return person;
    }
}

在Pet没有实现Serializable接口的情况下,看看控制台运行错误

1
2
3
4
5
6
7
8
9
Exception in thread "main" java.io.NotSerializableException: serialize.Pet
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at serialize.TestSerializeAndDeserialize.serializePerson(TestSerializeAndDeserialize.java:36)
    at serialize.TestSerializeAndDeserialize.main(TestSerializeAndDeserialize.java:25)

FindBugs提示错误

1
2
3
Bug: Class serialize.Person defines non-transient non-serializable instance field pet
This Serializable class defines a non-primitive instance field which is neither transient, Serializable, or java.lang.Object, and does not appear to implement the Externalizable interface or the readObject() and writeObject() methods.  Objects of this class will not be deserialized correctly if a non-Serializable object is stored in this field.
Rank: Troubling (14), confidence: HighPattern: SE_BAD_FIELD Type: Se, Category: BAD_PRACTICE (Bad practice)

结论:

由于Person中的Pet属性没有实现序列化接口serializable,在执行序列化,反序列化过程中就会出错。

解决办法就是将Pet也实现序列化接口。




     本文转自巧克力黒 51CTO博客,原文链接:http://blog.51cto.com/10120275/1752503,如需转载请自行联系原作者






网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注