lambda 在创建后对其进行序列化

2022-09-04 02:50:49

我可以使用以下语法序列化 lambda

Runnable r = (Runnable & Serializable) () -> System.out.println("");
try (ObjectOutput oo = new ObjectOutputStream(new ByteArrayOutputStream())) {
  oo.writeObject(r);
}

但是,如果我从客户端代码收到 lambda,并且它尚未正确转换,则无法对其进行序列化。

如何在不更改其定义的情况下序列化下面的r

Runnable r = () -> System.out.println("");

我试图序列化一个“派生”对象:

Runnable r1 = (Runnable & Serializable) r::run;
Runnable r2 = (Runnable & Serializable) () -> r.run();

但在每种情况下,都会失败,并带有 .oo.writeObject(rxxx);NotSerializableException


答案 1

这是正确的,并且是设计使然。正如您无法在实例化后获取不可序列化的对象并使其可序列化一样,一旦创建了 lambda,就会设置其可序列化性。

如果 lambda 的目标类型可序列化(并且其捕获的参数可序列化),则该 lambda 是可序列化的。您的第一个示例是可序列化的,因为目标类型是交集(Runnable & Serializable)。您的两次转换尝试都失败了,因为在这两种情况下,都是一个不可序列化的捕获变量,因此生成的 lambda 表达式/方法引用是不可序列化的。(绑定方法引用的接收器充当捕获的变量。rr


答案 2