【发布时间】:2014-12-12 21:33:19
【问题描述】:
我在网络上做了一个小研究,并回顾了这个网站上的相关主题,但答案是矛盾的:有人说不可能,有人说有可能,但很危险。
目标是将匿名类的对象作为 RMI 方法的参数传递。由于 RMI 要求,这个类必须是可序列化的。这里没问题,让类Serializable很容易。
但是我们知道内部类的实例持有对外部类的引用(匿名类是内部类)。正因为如此,当我们序列化内部类的实例时,外部类的实例和字段一样被序列化。这就是问题所在:外部类不可序列化,更重要的是——我不想序列化它。我想做的只是发送匿名类的实例。
简单示例 - 这是一个 RMI 服务,其方法接受 Runnable:
public interface RPCService {
Object call(SerializableRunnable runnable);
}
这就是我想要调用该方法的方式
void call() {
myRpcService.call(new SerializableRunnable() {
@Override
public Object run {
System.out.println("It worked!");
}
}
}
如您所见,我想做的是向另一方发送“动作”——系统 A 描述了应该在系统 B 上运行的代码。这就像在 Java 中发送脚本一样。
如果可能的话,我很容易看到一些危险的后果:例如,如果我们从 Runnable 访问外部类的字段或捕获的最终变量 - 我们会遇到麻烦,因为调用者实例不存在。另一方面,如果我在 Runnable 中使用安全代码(编译器可以检查它),那么我看不到禁止此操作的理由。
因此,如果有人知道,writeObject() 和 readObject() 方法应该如何在匿名类中正确覆盖,或者如何引用外部类 transient,或者解释为什么在 java 中不可能,这将非常有帮助。
UPD
另一个需要考虑的重要事项:外部类不存在于将执行方法(系统 B)的环境中,这就是为什么应该完全排除有关它的信息以避免NoClassDefFoundError。
【问题讨论】:
-
现在你没有机会了。除了非常核心的方式,比如将类的字节码发送到另一端并在那里恢复
标签: java serialization rmi anonymous-class