Explain Codes LogoExplain Codes Logo

How to serialize a lambda?

java
lambda
serialization
java-8
Anton ShumikhinbyAnton Shumikhin·Feb 21, 2025
TLDR

To serialize a Java lambda, categorize it as Serializable and apply the right casting:

Serializable serializableLambda = (Serializable & Predicate<Integer>) n -> n > 0;

Now, this lambda can be serialized as long as it isn't wrapping any non-serializable state.

Going beyond: Serializing state-holding lambdas

When your lambda is clutching some state, ensure that the state is itself Serializable. Otherwise, you can expect NotSerializableException to crash your party. Here's how:

class StateHolder implements Serializable { private int threshold = 0; // Note: Must be Serializable public Predicate<Integer> getLambda() { return (Serializable & Predicate<Integer>) n -> n > threshold; // Lambda feels safe now } }

Here, the enclosing StateHolder must be Serializable for the lambda to serialize without complaints.

Framework magic: Serializable function interfaces

Tools like Apache Beam smartly define their own SerializableFunction interfaces to avoid this serialization dilemma:

SerializableFunction<Integer, Boolean> isPositive = n -> n > 0; // Sweet & short, isn't it?

Using such interfaces shortens code and brings more clarity.

Advanced serialization: Get your hands dirty

Beyond the basic code snippets, there are more subtle methods to serialize lambdas:

Handling non-serializable states

For those stubborn non-serializable objects, try transforming them into serializable friends before capture. Else, you could use transient fields.

Turbo mode: Kryo for the win

Systems like Kryo specialize in high-performance serialization, which could give your lambda a nitrous boost in serializing expressions.

Nature of the beast: LambdaMetafactory

Want full control? Use LambdaMetafactory to have surgical precision over the deserialization process, crafting your very own lambda instantiation.

Watch out: Type erasure stings

Don't get caught by type erasure hazards in generics; your runtime type may walk a different runway after deserialization.

Banish boilerplates

In projects where lambda serialization is as frequent as coffee breaks, create utility methods or classes to encapsulate the serialization magic:

public class Lambdas { @SuppressWarnings("unchecked") public static <T extends Serializable> T serializable(T lambda) { return (T) lambda; // A serialized crow in feather's clothing } }

Now, using it is minimalistic:

Predicate<Integer> serializableLambda = Lambdas.serializable(n -> n > 0); // Disguise is perfect