0

我有一个涉及 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; }
}

cObj在 RMI Registry 中注册了 Circle 类的对象:

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 类定义。

帮助表示赞赏。

4

1 回答 1

1

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

  1. 使用 RMI 代码库功能。您需要查看它,因为它是一个太大的话题,无法在此处讨论,但基本上它可以从 RMI 服务器指定的其他位置进行类加载。

  2. 使它成为一个导出的远程对象,这样对它的调用也是 RMI 调用。通过使 Shape 扩展 Remote,您已经完成了一半,但您还需要导出 Circle,方法是使其扩展 UnicastRemoteObject 或在构造时调用 UnicastRemoteObject.exportObject()。

在我看来,通过扩展 Remote 你真的打算一直做(2)。如果你这样做,你不需要使 Shape 扩展 Serializable。如果您这样做 (2),那么让 Shape 扩展 Remote 毫无意义。您应该删除其中一个:它们是相互排斥的。

于 2013-01-31T22:17:34.050 回答