java - 在 RMI 中将子类对象转换为父类(super class)引用

标签 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接口(interface)类型。

我会如何看待这个问题,可能是客户端执行查找并找到具有 cObj 名称和 Circle 类型的对象。服务器知道 Circle 是 Shape 的子类型,并序列化该对象并将其发送到客户端。现在,我不确定客户端是否可以将其转换为父类(super class)(Shape)类型,而无需访问 Circle 类定义。

感谢帮助。

最佳答案

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

  1. 使用 RMI 代码库功能。您需要查一下这个,因为它是一个太大的主题,无法在这里讨论,但基本上它使得从 RMI 服务器指定的附加位置加载类成为可能。

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

在我看来,通过扩展 Remote,你实际上是想一直做 (2)。如果这样做,则不需要使 Shape 扩展可序列化。如果您执行(2),则让 Shape 扩展 Remote 是没有意义的。您应该删除其中一个:它们是相互排斥的。

关于java - 在 RMI 中将子类对象转换为父类(super class)引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14627840/

相关文章:

java - 在java中的windows下根据给定的COMx名称查找com端口的 "FriendlyName"

c# - WCF 错误 'There was an error while trying to serialize parameter...'

Java 接口(interface)及其在集合中的使用

json - 如何在 Asp.net Core Web Api 中默认使用 Newtonsoft.Json?

Java 可选参数化接口(interface)

c++ - 模板化虚函数,管理来自单个类的不同类属性

java - Apache POI - 丢失单元策略

java - spring-batch(或其他地方)中是否有可重试的 JobRepository 'out-of-the-box' ?

java - 将 Java 字节读取为 CharSet

java - 如何仅序列化 Java 类中的极少数属性