我想知道对特定类型的任意对象的实例方法的引用是否可序列化?
示例:
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
}
SerializableConsumer
@FunctionalInterface
public interface SerializableConsumer<T> extends Consumer<T>, Serializable {
}
和字段是:
SerializableConsumer<MyClass> serializableMethod = MyClass::foo;
EDITED
答案 0 :(得分:6)
假设SerializableFunction
引用扩展Serializable
的类型,方法引用将是可序列化的。您要求的特定类型的方法参考没有什么特别之处。
最值得注意的是,“对任意对象的实例方法的引用”没有捕获MyClass
的任何实例,因此,MyClass
不是Serializable
的事实不是重要。如果你引用像object::foo
之类的特定实例的实例方法会有所不同,因为在这种情况下,对象也必须被序列化,如果它的类没有实现,它将在运行时失败Serializable
。
什么行不通,是将void
方法称为返回类型Function
的{{1}}。我不知道您的Void
是如何定义的,但如果它等同于SerializableFunction<MyClass, Void>
,则无效。
当您拥有适当的功能界面时,序列化方法参考是没有问题的:
Function<MyClass, Void>&Serializable
如上所述,对特定实例的引用必须序列化目标实例,因此,取决于该实例的可序列化性,所以
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());
}
}
将在运行时使用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();
}
}
失败,除非您更改java.io.NotSerializableException: MyClass
以实施MyClass
。
答案 1 :(得分:0)
我知道你可以序列化一个lambda表达式(你可以看到here)
现在,您想要做的只是自己序列化变量?还是方法?...我不知道为什么,但我认为你不能。也许你可以采取其他方式,比如创建一个lambda并序列化它,就像上面的帖子一样:
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");