Как я могу элегантно сериализовать лямбду?
Например, код ниже выдает a 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();
}
}
java
serialization
lambda
java-8
assylias
источник
источник
Ответы:
Java 8 предоставляет возможность привести объект к пересечению типов путем добавления нескольких границ . Поэтому в случае сериализации можно написать:
И лямбда автоматически становится сериализуемой.
источник
Та же самая конструкция может использоваться для ссылок на метод. Например этот код:
определяет лямбда-выражение и ссылку на метод с сериализуемым целевым типом.
источник
Очень безобразный актерский состав. Я предпочитаю определять Serializable расширение для функционального интерфейса, который я использую
Например:
тогда метод, принимающий лямбду, можно определить так:
и вызывая функцию, вы можете передать свою лямбду без какого-либо уродливого преобразования
источник
SerializableRunnable
« фиктивного »интерфейса»Если кто-то попадет сюда при создании кода Beam / Dataflow:
Beam имеет свой собственный интерфейс SerializableFunction, поэтому нет необходимости в фиктивном интерфейсе или подробном приведении.
источник
Если вы хотите перейти на другую платформу сериализации, такую как Kryo , вы можете избавиться от нескольких границ или требований, которые должен реализовывать реализованный интерфейс
Serializable
. Подход кInnerClassLambdaMetafactory
чтобы всегда генерировать код, необходимый для сериализацииLambdaMetaFactory
время десериализацииПодробности и код смотрите в этой записи блога.
источник