Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialization of a lambda after its creation

I can serialize a lambda with the following syntax:

Runnable r = (Runnable & Serializable) () -> System.out.println("");
try (ObjectOutput oo = new ObjectOutputStream(new ByteArrayOutputStream())) {
  oo.writeObject(r);
}

However if I receive the lambda from a client code and it has not been cast appropriately, I can't serialize it.

How can I serialize r below without changing its definition:

Runnable r = () -> System.out.println("");

I have tried to serialize a "derived" object:

Runnable r1 = (Runnable & Serializable) r::run;
Runnable r2 = (Runnable & Serializable) () -> r.run();

but in each case, oo.writeObject(rxxx); fails with a NotSerializableException.

like image 870
assylias Avatar asked Aug 19 '14 19:08

assylias


People also ask

How can lambda expression be serialized?

We can serialize a lambda expression if its target type and its captured arguments have serialized. However, like inner classes, the serialization of lambda expressions is strongly discouraged. As the lambda function is not serialized by default we simply have to cast our lambda to java. io.

Is serializable a functional interface?

Serializable is a bit of a unique interface in this regards, as there is nothing you actually need to implement. Without making this cast, the lambda will be considered unserializable, which does not make Kryo happy.

What happens during serialization?

Serialization is the process of converting a data object—a combination of code and data represented within a region of data storage—into a series of bytes that saves the state of the object in an easily transmittable form.

Can functions be serialized?

At many instances when doing Ajax requests in Javascript, a serialize function comes in handy for creating a string in standard URL-encoded notation for the request parameters. The most widely used serialize function is that of jQuery which works great on forms.


1 Answers

This is correct, and by design. Just as you cannot take a non-serializable object and make it serializable after instantiation, once a lambda is created, its serializability is set.

A lambda is serializable if its target type is serializable (and its captured arguments are serializable.) Your first example is serializable because the target type is the intersection (Runnable & Serializable). Your two attempts to convert r fail because in both cases, r is a captured variable that is not serializable, and so the resulting lambda expression / method reference is not serializable. (The receiver for a bound method reference acts as a captured variable.)

like image 184
Brian Goetz Avatar answered Sep 20 '22 12:09

Brian Goetz