10

RMIの使用に関する変数の受け渡しに関するさまざまな記事を読みました。

RMIで参照によって変数を渡すことは不可能であると言う人もいます。例:これこれ

他の人がそれが可能であると言う間。例: これこれこれ

誰かがこれを片付けることができますか?:)

4

3 に答える 3

6

重要な注意:参照渡しがメソッド内の引数値を変更し、呼び出し元で元の変数を変更することを意味する場合、それはできません。あなたがしたいのがオブジェクトへの参照のコピーを渡すことであるなら、メソッドがあなたのオブジェクトと相互作用することを可能にするために...はい、あなたはそうすることができます。答えは、その2番目のオプションを検討します。

はい。ただし、RMIオブジェクトである必要があります。その場合、RMIスタブはコピーによって渡されます。

RMIは、引数と戻り値を2つの方法で渡します。

  1. オブジェクト全体をコピーする
  2. リモート参照を送信します(参照の場合はリモートである必要があります!)。

サンプル

私たちはサービスを持っていると思います。これはRMIオブジェクトであり、RMIレジストリを介して公開されるため、クライアントにアクセスできます。クライアントは(何かを作成するために)そのメソッドを呼び出すことができ、サービスはその新しく作成されたオブジェクトへの参照を返したいと考えています。シリアル化されたコピーではなく、サーバーのメモリ空間に作成されたオブジェクトへの参照。

import java.rmi.Remote;
import java.rmi.RemoteException;

// normally published object
public interface MyService extends Remote
{
    // creates something and return a "handle" to it
    public MyHandle createX(SomeSerializableObj param1) throws RemoteException;
}

// interface for object that the service will return a reference to...
public interface MyHandle extends Remote
{
    void doOne();
    void doTwo();
}

この例では、次のことができます。

MyServiceの実装を作成し、公開します

Registry registry = LocateRegistry.createRegistry(port);
MyService stub = (MyService) UnicastRemoteObject.exportObject(server, 0);
registry.bind("myService", stub);`

次に、一部のRMIクライアントがそれへの参照を取得できます

Registry registry = LocateRegistry.getRegistry(server, port);
MyService serv1 = (MyService) registry.lookup("myService");

また、サービスオブジェクトへの参照を使用すると、他のRMIオブジェクトへの参照を取得できます。

MyHandle handle1 = serv1.createX(...);
handle1.doOne()

この例では、メソッド引数はシリアル化され(Serializableクラスである必要があります)、返されるオブジェクトはサーバーで作成されたオブジェクトへのRMI参照です。

createX(...)の実装は次のようになります。

public MyHandle createX(...) {
   MyHandle handle = new MyHandleImpl(); // create an implementation
   createdHandlers.add(handle); // add it to some structure (just a sample)
   return handle; // return the implementation. RMI will send to client a RMI reference to this very instance
}
于 2012-06-25T10:28:54.023 に答える
3

あなたの参照の:

(1)RMIは参照渡しをサポートしていないと言います。同意します。

(2)RMIはin-outパラメータをサポートしていないと言います。同意します。

(3)参照による受け渡しと値による参照の受け渡しの間の通常の混乱を示しています。RMIは、Javaの他の部分と同様に、後者を実行します。

(4)間違っています。

(5)は単純に一貫性がありません。RMIには参照渡しはありません。

RMIのリモートの「値による参照」は、追加の考えられる障害モードを除いて、Javaのローカルの「値による参照」と意味的に本質的に違いはありません。

あなたが読んだことの意味は、非リモート参照の場合、RMIオブジェクトの引数と結果は、Javaの値による参照の引数受け渡しメソッドではなく、オブジェクトのシリアル化を介して値によって渡されるということです。

于 2012-06-25T23:12:22.650 に答える
0

いいえという言葉の本当の意味では、あなたはできません。

「参照」によって何かを渡すとき、実際に行っているのは、メモリ内の場所へのポインタを渡すことです。これは、呼び出し元と呼び出し先が同じプロセスであり、まったく同じヒープにアクセスできる場合に完全に機能します。しかし、コンピュータAからコンピュータBにメモリ参照を渡すことは無意味であり、AはBのメモリ*にアクセスできません。

ただし、RMIを使用すると、リモートオブジェクトへの「参照」を取得できますが、これはまったく同じではなく、事前に要求する必要があります。オブジェクトの1つをサーバーに渡すと、コピーが作成されます。

馬の口から直接(http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138781.html#3)

RMIは、標準のJavaオブジェクトシリアル化メカニズムを使用してオブジェクトを渡します。リモートオブジェクトへの参照である引数は、リモート参照として渡されます。メソッドの引数がプリミティブ型またはローカル(非リモート)オブジェクトの場合、ディープコピーがサーバーに渡されます。戻り値は同じ方法で処理されますが、反対方向に処理されます。RMIを使用すると、ローカルオブジェクトおよびリモートオブジェクトへの参照の完全なオブジェクトグラフを渡して返すことができます。

リモートオブジェクトを参照として渡すことはできますが、ローカルオブジェクトを参照としてサーバーに戻すことはできません。

*技術的には、大規模な分散共有メモリシステムでは可能ですが、OPが話しているのはそれではないかと思います。

于 2012-06-26T01:18:11.207 に答える