Вступление
Короткий пост, описывающий, как лямбда Java может быть сохранена в файл для повторного использования в другом процессе.
Сериализация Lambdas
Лямбды, представленные в Java 8, делают функции первоклассными гражданами (почти) на языке Java. Они устраняют необходимость в выделенном классе для хранения функции. Но как это работает под одеялом?
В действительности javac захватывает класс, содержащий функцию, добавляя статический метод, который содержит реализацию функции. Сайт вызова функции заменяется вызовом вновь добавленного статического метода. Для полного описания волшебства лямбда-реализации смотрите это
статья
Oracle услужливо предоставляет класс SerializableLambda, который реализует сериализуемую форму лямбды, предоставляя достаточное количество метаинформации для восстановления вызова. Все, что нам нужно сделать, — это преобразовать лямбду в Serializable, а затем использовать стандартные стандартные механизмы для упорядочения лямбды. Ниже приведено несколько полезных функций для сериализации и десериализации лямбды.
01
02
03
04
05
06
07
08
09
10
11
|
public static <F extends Function & Serializable> void serialise(F f, String name) throws Exception { try (var oos = new ObjectOutputStream( new FileOutputStream( new File(name)))) { oos.writeObject(f); } } public static <T, R, F extends Function<T, R>> F deserialise(String name) throws Exception { try (var ois = new ObjectInputStream( new FileInputStream(name))) { return (F) ois.readObject(); } } |
В функции сериализации я использую пересекающиеся типы, чтобы привести функцию к Serializable. Есть небольшой проект с тестовой базой
здесь, чтобы продемонстрировать сериализацию. Основной метод выполнения функций:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class Main { public static void main(String[] args) throws Exception { if ( false ) { serialise(s -> "hello - " + s, "func1" ); } System.out.println(deserialise( "func1" ).apply( "Greg" )); //rewrite func-1 serialise(s -> "goodbye - " + s, "func1" ); System.out.println(deserialise( "func1" ).apply( "Greg" )); } public static <F extends Function & Serializable> void serialise(F f, String name) throws Exception { try (var oos = new ObjectOutputStream( new FileOutputStream( new File(name)))) { oos.writeObject(f); } } public static <T, R, F extends Function<T, R>> F deserialise(String name) throws Exception { try (var ois = new ObjectInputStream( new FileInputStream(name))) { return (F) ois.readObject(); } } } |
У проекта есть серийная лямбда-функция «func-1» в корне. При запуске проекта func-1 будет перезаписан, поэтому второе выполнение даст результат, отличный от первого:
Первое исполнение:
привет — Грег
до свидания — Грег
Второе исполнение:
до свидания — Грег
до свидания — Грег
Надеюсь, вам понравилась эта небольшая статья и она показалась вам интересной.
Опубликовано на Java Code Geeks с разрешения Грега Хиггинса, партнера нашей программы JCG . См. Оригинальную статью здесь: сохраните свои лямбды на черный день — сохраните в файл Мнения, высказанные участниками Java Code Geeks, являются их собственными. |