Java序列化示例

在Java中, Serialization意味着将对象转换为字节流,可以将其保存到文件中或通过网络传输, Deserialization则相反。

序列化示例。

// Save object into a file.
    public static void writeObject(Object obj, File file) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(file);
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(obj);
            oos.flush();
        }
    }

反序列化示例。

// Get object from a file.
    public static Object readObject(File file) throws IOException, ClassNotFoundException {
        Object result = null;
        try (FileInputStream fis = new FileInputStream(file);
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            result = ois.readObject();
        }
        return result;
    }

1. POJO

查看一个简单的Person类,实现Serializable

Person.java
package com.mkyong.io.object;

import java.io.Serializable;
import java.math.BigDecimal;

public class Person implements Serializable {

    // optional, if missing, JVM will create it.
    // better declare as a version control.
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
    // dun save this field into file
    private transient BigDecimal salary;

    // getters, setters, toString, constructor

}

在Java中,需要序列化的对象必须实现Serializable接口,否则会遇到以下错误。

Terminal
Exception in thread "main" java.io.NotSerializableException: com.mkyong.io.object.Person

  at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185)
  at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
  at com.mkyong.io.object.ObjectUtils.writeObject(ObjectUtils.java:14)
  at com.mkyong.io.object.ObjectUtils.main(ObjectUtils.java:35)

2. Java序列化示例

参见注释以进行自我解释。

ObjectUtils.java
package com.mkyong.io.object;

import java.io.*;
import java.math.BigDecimal;

// serialization and deserialization
public class ObjectUtils {

    // Serialization
    // Save object into a file.
    public static void writeObject(Person obj, File file) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(file);
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(obj);
            oos.flush();
        }
    }

    // Deserialization
    // Get object from a file.
    public static Person readObject(File file) throws IOException, ClassNotFoundException {
        Person result = null;
        try (FileInputStream fis = new FileInputStream(file);
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            result = (Person) ois.readObject();
        }
        return result;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Person person = new Person("mkyong", 40, new BigDecimal(900));

        // object -> file
        ObjectUtils.writeObject(person, new File("person.obj"));

        // file to object
        Person obj = ObjectUtils.readObject(new File("person.obj"));
        System.out.println(obj);

    }
}

输出量

Terminal
Person{name='mkyong', age=40, salary=null}

什么是瞬态?
为什么薪水为零? 序列化期间,JVM会忽略所有transient字段。 如果我们需要在序列化期间排除特定对象的字段,请将其标记为transient.

3.什么是serialVersionUID?

如果缺少serialVersionUID ,则JVM将自动创建它。 serialVersionUID类似于版本号。 简而言之,如果我们将对象保存为1L ,则需要提供相同的1L来读取对象,否则会遇到不兼容的错误。

Person.java
public class Person implements Serializable {

    private static final long serialVersionUID = 1L;
    //...
}

例如,我们将serialVersionUID = 1L的对象保存到文件名person.obj 。 稍后,我们从对象中添加或删除一些字段,并将serialVersionUID更新为2L 。 现在,读取person.obj文件并尝试将其转换回修改后的对象,因为两个serialVersionUID不同,我们将遇到以下不兼容错误:

Terminal
Exception in thread "main" java.io.InvalidClassException: com.mkyong.io.object.Person;

  local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

	at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
	at com.mkyong.io.object.ObjectUtils.readObject(ObjectUtils.java:25)
	at com.mkyong.io.object.ObjectUtils.main(ObjectUtils.java:38)

下载源代码

$ git clone https://github.com/mkyong/core-java.git

$ cd java-io

参考文献

翻译自: https://mkyong.com/java/java-serialization-examples/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值