java serialization lambda java-8

java - ¿Cómo serializar una lambda?



serialization java-8 (4)

Elenco muy feo. Prefiero definir una extensión Serializable para la interfaz funcional que estoy usando

Por ejemplo:

interface SerializableFunction<T,R> extends Function<T,R>, Serializable {} interface SerializableConsumer<T> extends Consumer<T>, Serializable {}

entonces el método que acepta la lambda puede definirse como tal:

private void someFunction(SerializableFunction<String, Object> function) { ... }

y llamando a la función puedes pasar tu lambda sin ningún molde feo:

someFunction(arg -> doXYZ(arg));

¿Cómo puedo serializar elegantemente una lambda?

Por ejemplo, el siguiente código arroja una NotSerializableException . ¿Cómo puedo solucionarlo sin crear una interfaz "ficticia" de 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(); } }



La misma construcción se puede usar para referencias de métodos. Por ejemplo, este código:

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); } }

define una expresión lambda y una referencia de método con un tipo de objetivo serializable.


Si está dispuesto a cambiar a otro marco de serialización como Kryo , puede deshacerse de los múltiples límites o el requisito de que la interfaz implementada debe implementar Serializable . El enfoque es

  1. Modifique InnerClassLambdaMetafactory para generar siempre el código requerido para la serialización
  2. Llamar directamente a la LambdaMetaFactory durante la deserialización

Para detalles y código, vea esta publicación en el blog