Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaRMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()和扩展UnicastRemoteObject之间的区别是什么?_Java_Interface_Export_Rmi - Fatal编程技术网

JavaRMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()和扩展UnicastRemoteObject之间的区别是什么?

JavaRMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()和扩展UnicastRemoteObject之间的区别是什么?,java,interface,export,rmi,Java,Interface,Export,Rmi,我正在准备考试,我有一个问题,我希望这里有人能回答我 它是关于RMI和远程对象的。我想知道为什么这两种实现之间有这么大的差异。一个是扩展UnicastMemoteObject,另一个是将该对象作为UnicastMemoteObject导出 我真的不明白有什么不同 接口: public interface EchoI extends Remote { public String echo() throws RemoteException } 这是服务器代码(版本1): 这将是第2版: pu

我正在准备考试,我有一个问题,我希望这里有人能回答我

它是关于RMI和远程对象的。我想知道为什么这两种实现之间有这么大的差异。一个是扩展UnicastMemoteObject,另一个是将该对象作为UnicastMemoteObject导出

我真的不明白有什么不同

接口:

public interface EchoI extends Remote {
   public String echo() throws RemoteException
}
这是服务器代码(版本1):

这将是第2版:

public class EchoImpl implements EchoI {
    public static void main (String[] args) {
        EchoI echoService = new EchoImpl();
        EchoI stub = (EchoI) UnicastRemoteObject.exportObject(echoService, 0);
        Registry registry = LocateRegistry.getRegistry();
        registry.bind("echoService", stub);
        ...
    }
}
我的问题是:这两者有什么区别

在第一个版本中,注册表是显式创建的,而且远程对象是在重新绑定中创建的

我真的很好奇,为什么首先我需要自己创建注册表,而不需要显式导出对象,只需要使用
命名
重新绑定它。该对象以前是否已绑定到注册表,或者我是否可以改用绑定?如果对象以前没有绑定,并且重新绑定被排除,会发生什么

在第二个版本中,注册表似乎已经创建。 为什么绑定到命名与直接绑定到注册表相同

这就是我所想的:

  • 第一个类direclty实现接口UnicastRemoteObject,这意味着在运行时创建注册表,并将对象自动导出到RMI注册表
  • 由于对象已绑定到注册表,因此必须进行重新绑定而不是正常绑定
  • 后者明确地做到了这一切

java.rmi.server.UnicastRemoteObject用于使用java远程方法协议(JRMP)导出远程对象,并获取与远程对象通信的存根

对于下面的构造函数和静态
exportObject
方法,将获得要导出的远程对象的存根


在这里,您应该按照

进行操作。这里有两个问题

  • 您可以扩展
    UnicastRemoteObject
    或调用
    UnicastRemoteObject.exportObject()。
    具体操作由您自己决定。第一种是简单和自动的;第二种方法意味着您可以扩展另一个类

  • 您可以使用外部RMI注册表,也可以自己在服务器JVM中创建它。同样,你做什么取决于你,这两种方式都有好处

    这两个问题没有相互作用

  • 如果您
    扩展UnicastRemoteObject
    您还可以从
    hashCode()
    equals()
    方法中获得“远程语义”的好处,这样所有存根看起来都与导出它们的远程对象相同,但这在客户端没有实际用途,实际上,它只是为了支持RMI实现本身


  • 在需要扩展任何其他类的情况下,可以调用
    UnicastRemoteObject.exportObject()
    ,而不是扩展
    UnicastRemoteObject
    。我认为总体效果是一样的


    首先,使用
    命名
    类和
    注册表
    类绑定和重新绑定远程对象与类是否扩展
    UnicastRemoteObject
    的场景无关。请参阅以了解差异

    其次,扩展
    UnicastRemoteObject
    的类之间的区别在于,如果该类型的对象用作存根,那么您就不需要调用
    UnicastRemoteObject.exportObject
    来获取存根以便与注册表绑定。在您的版本1中,
    库impl
    必须扩展了
    UnicastRemoteObject
    ,事实上,
    EchoImpl
    无需为您的版本1扩展
    UnicastRemoteObject
    ,因为没有将
    EchoImpl
    的实例注册为注册表的远程对象


    第三,您提到如果执行
    rebind
    ,而不事先执行
    bind
    ,会发生什么。正如javadoc中所解释的,如果没有插入密钥名,它的行为将与第一次执行
    bind
    时的行为相同。

    顺便说一句,您的服务器代码版本1让我感到困惑,locateRegistry无法工作,因为它没有声明感谢您的回复,但它并没有真正为我澄清问题。。。。您更喜欢现在的代码吗?;-)现在编译器更喜欢您的代码,结果是相同的,对象在RMI注册表中以提供的名称注册,并且可由客户端访问。唯一的区别是重新绑定比绑定(如果已经绑定)更具容错性。为了再次吸引更多的男士,我会把你的问题投上一票——所以第一个版本比较安全,对吗?在几乎所有的教程中,RMI对象都是以后一种方式导出的,但在我看来,我更喜欢第一个版本,而不是另一个版本……正如前面提到的,它们是等效的。区别在于重新绑定不会抛出AlreadBoundExection,我也更喜欢您的第一个选项。在你的考试中,你可以描述一种方法,并提到还有另一种选择。质量差的链接至少有两个主要错误-1.
    public class EchoImpl implements EchoI {
        public static void main (String[] args) {
            EchoI echoService = new EchoImpl();
            EchoI stub = (EchoI) UnicastRemoteObject.exportObject(echoService, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.bind("echoService", stub);
            ...
        }
    }