将子类对象转换为RMI中的超类引用

时间:2013-01-31 14:15:07

标签: java serialization interface polymorphism rmi

我有一个涉及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类定义。

帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

如果您不想将Circle类部署到客户端,您有两种选择:

  1. 使用RMI代码库功能。你需要查看这个,因为这里讨论的主题太大了,但基本上它可以从RMI服务器指定的附加位置进行类加载。

  2. 将其设为导出的远程对象,以便对其进行调用也是RMI调用。你已经将Shape扩展为Remote,但你也需要导出Circle,方法是扩展UnicastRemoteObject,或者在构造时调用UnicastRemoteObject.exportObject()。

  3. 在我看来,通过扩展遥控器你真的打算一直做(2)。如果这样做,您不需要使Shape扩展Serializable。如果你做(2)那么将Shape扩展为Remote是没有意义的。你应该删除一个或另一个:它们是互相排斥的。