Java 如何序列化lambda?
如何优雅地序列化lambda 例如,下面的代码抛出一个Java 如何序列化lambda?,java,serialization,lambda,java-8,Java,Serialization,Lambda,Java 8,如何优雅地序列化lambda 例如,下面的代码抛出一个NotSerializableException。如何在不创建SerializableRunnable虚拟接口的情况下修复它 public static void main(String[] args) throws Exception { File file = Files.createTempFile("lambda", "ser").toFile(); try (ObjectOutput oo = new ObjectO
NotSerializableException
。如何在不创建SerializableRunnable
虚拟接口的情况下修复它
public static void main(String[] args) throws Exception {
File file = Files.createTempFile("lambda", "ser").toFile();
try (ObjectOutput oo = new ObjectOutputStream(new FileOutputStream(file))) {
Runnable r = () -> System.out.println("Can I be serialized?");
oo.writeObject(r);
}
try (ObjectInput oi = new ObjectInputStream(new FileInputStream(file))) {
Runnable r = (Runnable) oi.readObject();
r.run();
}
}
Java8引入了实现的可能性。因此,在序列化的情况下,可以写入:
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");
并且lambda自动成为可序列化的。相同的结构可用于方法引用。例如,此代码:
import java.io.Serializable;
public class Test {
static Object bar(String s) {
return "make serializable";
}
void m () {
SAM s1 = (SAM & Serializable) Test::bar;
SAM s2 = (SAM & Serializable) t -> "make serializable";
}
interface SAM {
Object action(String s);
}
}
定义具有可序列化目标类型的lambda表达式和方法引用。如果您愿意切换到其他类似的序列化框架,则可以消除多个边界或实现的接口必须实现可序列化的要求。方法是
InnerClassLambdaMetafactory
以始终生成序列化所需的代码LambdaMetaFactory
有关详细信息和代码,请参见此非常难看的演员阵容。我更喜欢为我正在使用的函数接口定义一个可序列化的扩展 例如:
interface SerializableFunction<T,R> extends Function<T,R>, Serializable {}
interface SerializableConsumer<T> extends Consumer<T>, Serializable {}
如果有人在创建梁/数据流代码时摔倒在这里:
Beam有自己的接口,因此不需要虚拟接口或详细的强制转换。非常有趣-此功能似乎非常强大。在铸造lambdas之外,有没有使用这种铸造表达式?例如,现在是否也可以对普通匿名类执行类似操作?@Balder添加了强制转换到交叉点类型的功能,以便为lambdas的类型推断提供目标类型。因为AIC有一个清单类型(即,它的类型不是推断的),所以将AIC转换为交集类型是没有用的。(这是可能的,只是没有用。)要让AIC实现多个接口,您必须创建一个扩展所有接口的新子接口,然后对其进行实例化。这会不会产生一个编译器警告,说没有定义serialVersionUID?注意:只有在构造期间应用转换时,这才有效。下面将抛出一个ClassCastException:Runnable r=()->System.out.println(“Serializable!”);Runnable-serializableR=(Runnable&Serializable)r@B正文是也请参见:虽然这是可能的(请参见所选答案),但每个人都应该三思而后行。我喜欢这个答案,因为这样的话,任何你没有写的外部调用程序都可以自动序列化。若您希望提交的对象是可序列化的,那个么您的接口应该是可序列化的,这是接口的一个要点。然而,问题是“没有创建
SerializableRunnable
'dummy'接口”,帖子被移到了这里:
private void someFunction(SerializableFunction<String, Object> function) {
...
}
someFunction(arg -> doXYZ(arg));