Java 序列化机制假定反序列化 JVM 知道类,它不发送类定义。特别是,当您序列化一个Class
对象时,您不会发送该类的字节码,而只是指示接收 VM 查找Class
具有特定名称的类的对象。
还要注意,一个Class
对象代表一个在JVM 中定义的类,即该类的字节码已经被加载。在加载类后尝试编译到类以生成该字节码几乎没有意义。
因此,我们需要以某种方式将类定义提供给客户端。最简单的方法是像客户端需要的任何其他类一样执行此操作(通过将其打包到客户端的 jar 文件中,或者您用来安装客户端程序的任何方式)。如果这不可能,您可以通过网络加载类定义,例如使用 a URLClassLoader
,或者您可以通过序列化流发送类文件,并在客户端接收到它后使用ClassLoader.defineClass
加载类。
PS:这个问题与类是否命名完全无关。以下测试代码表明匿名类的对象可以很好地序列化和反序列化(如果接收VM具有类定义):
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
Serializable payload = new Serializable() {
@Override
public String toString() {
return "hello from the anonymous class";
}
};
oos.writeObject(payload);
oos.writeObject(payload.getClass());
}
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
System.out.println(in.readObject());
System.out.println(in.readObject());
}