为什么java.util.Optional不是Serializable,如何序列化带有此类字段的对象 [英] Why java.util.Optional is not Serializable, how to serialize the object with such fields

查看:34
本文介绍了为什么java.util.Optional不是Serializable,如何序列化带有此类字段的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Enum 类是可序列化的,所以用 enum 序列化对象是没有问题的.另一种情况是 class 具有 java.util.Optional 类的字段.在这种情况下,抛出以下异常:java.io.NotSerializableException: java.util.Optional

The Enum class is Serializable so there is no problem to serialize object with enums. The other case is where class has fields of java.util.Optional class. In this case the following exception is thrown: java.io.NotSerializableException: java.util.Optional

这样的类怎么处理,怎么序列化?是否可以将此类对象发送到远程 EJB 或通过 RMI?

How to deal with such classes, how to serialize them? Is it possible to send such objects to Remote EJB or through RMI?

示例如下:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Optional;

import org.junit.Test;

public class SerializationTest {

    static class My implements Serializable {

        private static final long serialVersionUID = 1L;
        Optional<Integer> value = Optional.empty();

        public void setValue(Integer i) {
            this.i = Optional.of(i);
        }

        public Optional<Integer> getValue() {
            return value;
        }
    }

    //java.io.NotSerializableException is thrown

    @Test
    public void serialize() {
        My my = new My();
        byte[] bytes = toBytes(my);
    }

    public static <T extends Serializable> byte[] toBytes(T reportInfo) {
        try (ByteArrayOutputStream bstream = new ByteArrayOutputStream()) {
            try (ObjectOutputStream ostream = new ObjectOutputStream(bstream)) {
                ostream.writeObject(reportInfo);
            }
            return bstream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

推荐答案

这个答案是针对标题中的问题难道 Optional 不是 Serializable?"的回答.简短的回答是 Java Lambda (JSR-335) 专家组 考虑并拒绝了它.那个注释,以及这个这个 表示主要设计Optional 的目标是在返回值可能不存在时用作函数的返回值.目的是调用者立即检查 Optional 并提取实际值(如果存在).如果该值不存在,调用者可以替换默认值、抛出异常或应用一些其他策略.这通常是通过在返回 Optional 值的流管道(或其他方法)的末端链接流畅的方法调用来完成的.

This answer is in response to the question in the title, "Shouldn't Optional be Serializable?" The short answer is that the Java Lambda (JSR-335) expert group considered and rejected it. That note, and this one and this one indicate that the primary design goal for Optional is to be used as the return value of functions when a return value might be absent. The intent is that the caller immediately check the Optional and extract the actual value if it's present. If the value is absent, the caller can substitute a default value, throw an exception, or apply some other policy. This is typically done by chaining fluent method calls off the end of a stream pipeline (or other methods) that return Optional values.

从来没有打算将 Optional 用于其他方式,例如 可选方法参数作为字段存储在对象中.并且通过扩展,使 Optional 可序列化将使其能够持久存储或通过网络传输,这两者都鼓励使用远远超出其原始设计目标的用途.

It was never intended for Optional to be used other ways, such as for optional method arguments or to be stored as a field in an object. And by extension, making Optional serializable would enable it to be stored persistently or transmitted across a network, both of which encourage uses far beyond its original design goal.

通常有比在字段中存储 Optional 更好的方法来组织数据.如果 getter(例如问题中的 getValue 方法)从字段中返回实际的 Optional,它会强制每个调用者实施一些处理空值的策略.这可能会导致调用者之间的行为不一致.通常最好让该字段在设置时应用某些策略的任何代码集.

Usually there are better ways to organize the data than to store an Optional in a field. If a getter (such as the getValue method in the question) returns the actual Optional from the field, it forces every caller to implement some policy for dealing with an empty value. This will likely lead to inconsisent behavior across callers. It's often better to have whatever code sets that field apply some policy at the time it's set.

有时人们希望将 Optional 放入集合中,例如 List>Map>.这通常也是一个坏主意.将 Optional 的这些用法替换为 Null-Object 值通常会更好(不是实际的 null 引用),或者只是从集合中完全省略这些条目.

Sometimes people want to put Optional into collections, like List<Optional<X>> or Map<Key,Optional<Value>>. This too is usually a bad idea. It's often better to replace these usages of Optional with Null-Object values (not actual null references), or simply to omit these entries from the collection entirely.

这篇关于为什么java.util.Optional不是Serializable,如何序列化带有此类字段的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆