我在网上做了一个小型的研究,并回顾了这个网站上的相关主题,但答案是矛盾的:有些人说这是不可能的,其他人说这是可能的,但是很危险。是否可以在没有外部类的情况下序列化匿名类?
目标是传递匿名类的对象作为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
。
现在你没有机会了。除了非常hardcore的方式,如发送类的字节码到另一边,并在那里恢复 – talex 2014-10-17 10:35:18