美文网首页java
JDK序列化官方指南

JDK序列化官方指南

作者: spraysss | 来源:发表于2019-10-25 16:12 被阅读0次

在网络中数据传输都是以字节数组传输的,而在java程序中操作的是类对象。java程序中对象到对象的传递在网络中的传输过程为:

  • 将对象序列化为字节数组发送到网络的接收方
  • 网络接收方接收到字节数组反序列化为对象

java语言提供了一整套完成的序列化框架用于完成对象的序列化和反序列化

Special handling is required for arrays, enum constants, and objects of type Class, ObjectStreamClass, and String. Other objects must implement either the Serializable or the Externalizable interface to be saved in or restored from a stream

除了数组,枚举类型,ObjectStreamClassString类型,其他对象序列化必须实现SerializableExternalizable 接口

For a Serializable class, Object Serialization can automatically save and restore fields of each class of an object and automatically handle classes that evolve by adding fields or supertypes. A serializable class can declare which of its fields are saved or restored, and write and read optional values and objects.
For an Externalizable class, Object Serialization delegates to the class complete control over its external format and how the state of the supertype(s) is saved and restored.

显示指定序列化字段

默认情况下,不使用transient 修饰的字段都是可以序列化的,也可以使用如下方式显示指定序列化字段

class List implements Serializable {
    List next;

    private static final ObjectStreamField[] serialPersistentFields
                 = {new ObjectStreamField("next", List.class)};

}

Serializable接口

序列化和无参构造函数的关系
  1. 单一对象,无继承关系:若想实现序列化与反序列化,则必须实现序列化接口,否则报异常:NotSerializableException
  2. 对象间有继承关系,但无引用关系,若想实现序列化与反序列化,则父类必须实现序列化接口或提供无参构造函数,否则报invalidClassException
  3. 对象间有继承关系,并且有引用关系,若想实现序列化与反序列化,则父类必须实现序列化接口
    具体细节和demo可以参考这篇博客
    https://blog.csdn.net/zh15732621679/article/details/79803105
方法
  • private void writeObject 自定义序列化
  • private void readObject 自定义反序列化
  • writeReplace
  • readResolve

Externalizable 接口

  • writeExternal
  • readExternal
  • writeReplace
  • readResolve

Writing to an Object Stream

序列化今天的日期到文件

    FileOutputStream f = new FileOutputStream("tmp");
    ObjectOutput s = new ObjectOutputStream(f);
    s.writeObject("Today");
    s.writeObject(new Date());
    s.flush();
  • 序列化对象使用ObjectOutputwriteObject方法
  • ObjectOutputStream can be extended to customize the information about classes in the stream or to replace objects to be serialized. Refer to the annotateClass and replaceObject method descriptions for details.

Reading from an Object Stream

从文件中反序列化出日期

FileInputStream in = new FileInputStream("tmp");
    ObjectInputStream s = new ObjectInputStream(in);
    String today = (String)s.readObject();
    Date date = (Date)s.readObject();
  • 序列化对象使用ObjectInputreadObject方法
  • ObjectInputStream can be extended to utilize customized information in the stream about classes or to replace objects that have been deserialized. Refer to the resolveClass and resolveObject method descriptions for details.

Documenting Serializable Fields and Data for a Class

序列化有关的java doc注解:

  • @serial
  • @serialField
  • @serialData

demo

public class SerdeDemo {


    static class User implements Serializable {

        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }

        private String username;
        transient private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
            objectOutputStream.defaultWriteObject();
            objectOutputStream.writeObject(password);

        }
        private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
            objectInputStream.defaultReadObject();
            password=(String)objectInputStream.readObject();
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        User user=new User("xiaoming","ABC123");
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(user);

        InputStream inputStream=new ByteArrayInputStream(outputStream.toByteArray());
        ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
        User user1=(User)objectInputStream.readObject();
        System.out.println(user1);
    }
}

默认行为不会序列化transient 修饰的字段,可以通过writeObject,readObject实现自定义的序列化

参考

https://docs.oracle.com/en/java/javase/13/docs/specs/serialization/index.html

相关文章

  • JDK序列化官方指南

    在网络中数据传输都是以字节数组传输的,而在java程序中操作的是类对象。java程序中对象到对象的传递在网络中的传...

  • 关于WebLogic Server WLS 组件存在远程命令执行

    上周,我们公布了JDK XmlDecoder反序列化这一漏洞(jdk紧急漏洞,XMLDecoder反序列化攻击),...

  • Java 序列化之 Externalizable

    相关文章: Java 序列化 之 Serializable JDK中除了提供 Serializable 序列化接口...

  • Cereal快速入门

    本文主要参考官方使用指南。 Cereal是一个轻便的C++序列化工具。 安装使用 为了在项目中使用cereal,只...

  • Java常用序列化方式

    常用序列化方式 jdk自带对象序列化 对象需要实现Serializable接口 通过ObjectOutputStr...

  • Jmeter下载教程;历史版本;汉化

    Jmeter历史版本地址:历史版本 Jmeter官方安装地址:官方地址 安装JDK JDK官方安装地址:官方地址,...

  • golang学习资源

    • golang官方文档• golang官方指南• golang官方指南目录版• 怎样编写golang代码• 地道...

  • Oracle JDK11升级指南 - Oracle JDK M

    Oracle JDK Migration Guide JDK11变化详解,JDK8升级JDK11详细指南 JDK1...

  • rabbitmq采坑记

    rabbitmq序列化 生产者序列化 ,默认是jdk序列化 消费者序列化,不写的话,只能用字节数组接收,不能转换成...

  • java序列化框架对比

    目录 jdk 自带对象序列化类ObjectInput(Out)Stream 1.无法跨语言。这应该是java序列化...

网友评论

    本文标题:JDK序列化官方指南

    本文链接:https://www.haomeiwen.com/subject/mnxcmctx.html