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

本文介绍Java中序列化的基本概念及其实现方式,并通过一个具体的Person类实例演示了序列化和反序列化的完整流程。强调了当类包含非序列化字段时可能遇到的问题,并给出了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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,如需转载请自行联系原作者






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值