I want to know if reference to an instance method of an arbitrary object of a particular type is serializable or not?
Example:
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
}
SerializableConsumer
@FunctionalInterface
public interface SerializableConsumer<T> extends Consumer<T>, Serializable {
}
and field is:
SerializableConsumer<MyClass> serializableMethod = MyClass::foo;
EDITED
Assuming that SerializableFunction
refers to a type that extends Serializable
, the method reference will be serializable. There is nothing special about the particular type of method reference your are asking for.
Most notably, the “reference to an instance method of an arbitrary object” is not capturing any instance of MyClass
, hence, the fact that MyClass
isn’t Serializable
is not important. It would be different if you were referring to an instance method of a particular instance like object::foo
, as in that case, the object had to be serialized as well, which will fail at runtime, if its class doesn’t implement Serializable
.
What will not work, is to refer to a void
method as a Function
of return type Void
. I don’t know how your SerializableFunction<MyClass, Void>
is defined, but if it is equivalent to Function<MyClass, Void>&Serializable
, it will not work.
When you have an appropriate functional interface, serializing the method reference is no problem:
import java.io.*;
import java.util.function.Consumer;
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Consumer<MyClass> consumer = (Consumer<MyClass>&Serializable)MyClass::foo;
byte[] serialized;
try(ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(consumer);
oos.flush();
serialized=baos.toByteArray();
}
Consumer<MyClass> deserialized;
try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized);
ObjectInputStream ois=new ObjectInputStream(bais)) {
deserialized = (Consumer<MyClass>)ois.readObject();
}
deserialized.accept(new MyClass());
}
}
As said, references to a specific instance have to serialize the target instance, hence, depend on the serializability of that instance so
import java.io.*;
import java.util.function.Consumer;
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Runnable runnable = (Runnable&Serializable)new MyClass()::foo;
byte[] serialized;
try(ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(runnable);
oos.flush();
serialized=baos.toByteArray();
}
Runnable deserialized;
try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized);
ObjectInputStream ois=new ObjectInputStream(bais)) {
deserialized = (Runnable)ois.readObject();
}
deserialized.run();
}
}
will fail at runtime with a java.io.NotSerializableException: MyClass
, unless you change MyClass
to implement Serializable
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With