我有一个涉及RMI,序列化和运行时多态的问题。
我的RMI服务器如下:
public interface Shape extends Remote, Serializable {
public double getArea() throws RemoteException;
}
public class Circle implements Shape {
double radius;
public Circle( double r) { radius = r; }
public double getArea() { return Math.PI * radius * radius; }
}
Circle类的对象cObj
已在RMI注册表中注册:
Circle cObj = new Circle (10);
registry.bind("cObj", cObj);
现在,在客户端,我在CLASSPATH上有Shape.class文件,但它在CLASSPATH上没有Circle.class文件。 RMI客户端是否可以在下面执行?
Shape obj = (Shape) registry.lookup("cObj");
obj.getArea();
请注意,Circle.class不在RMI客户端的CLASSPATH中,并且客户端上的代码无论如何都不直接引用Circle类。它只引用Shape接口类型。
我如何看待这个,可能是客户端执行查找并找到具有cObj名称和Circle类型的对象。服务器知道Circle是Shape的子类型,并序列化对象并将其发送到客户端。现在,我不确定客户端是否可以将其转换为超类(Shape)类型而无法访问Circle类定义。
帮助表示赞赏。
答案 0 :(得分:1)
如果您不想将Circle类部署到客户端,您有两种选择:
使用RMI代码库功能。你需要查看这个,因为这里讨论的主题太大了,但基本上它可以从RMI服务器指定的附加位置进行类加载。
将其设为导出的远程对象,以便对其进行调用也是RMI调用。你已经将Shape扩展为Remote,但你也需要导出Circle,方法是扩展UnicastRemoteObject,或者在构造时调用UnicastRemoteObject.exportObject()。
在我看来,通过扩展遥控器你真的打算一直做(2)。如果这样做,您不需要使Shape扩展Serializable。如果你不做(2)那么将Shape扩展为Remote是没有意义的。你应该删除一个或另一个:它们是互相排斥的。