2012-06-25 12 views

Respuesta

5

Nota importante: sipase por referencia medios de modificación valor del argumento dentro del método y el cambio en la variable original de llamadas, no se puede. Si lo que quiere hacer es pasar una copia de una referencia a un objeto, para permitir que el método interactúe con algún objeto suyo ... sí puede. La respuesta explora esa segunda opción.

Sí. Pero tiene que ser un objeto RMI. En ese caso, se pasará un código RMI por copia.

RMI pasa argumentos y valores de retorno de dos maneras: (! Que tiene que ser a distancia si su referencia)

  1. copiar el objeto completo
  2. enviar un mando a distancia referencia .

Muestra

supongo que tenemos un servicio. Es un objeto RMI, publicado a través del registro RMI, por lo que es accesible para los clientes. El cliente puede llamar a un método (para crear algo) y el servicio quiere devolver una referencia a ese objeto recién creado. No es una copia serializada sino una referencia al objeto creado en el espacio de memoria del servidor.

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(); 
} 

En este ejemplo, usted podría:

Crear una implementación de MyService y publicarla

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

y luego, algún cliente RMI podría obtener una referencia a ella

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

y con una referencia al objeto de servicio podría obtener una referencia a otro objeto RMI.

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

En este ejemplo se serializa el argumento de método (que debería ser una clase Serializable) mientras que el objeto devuelto es una referencia RMI a un objeto creado en el servidor.

La implementación de createX (...) Podría ser:

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 
} 
+0

gracias :) pero yo no lo entiendo muy bien su respuesta :( puede ofrecerle un ejemplo por favor? :) – MBZ

+0

Claro ... No tengo un ejemplo que nos ocupa en ese momento ... – helios

+1

@MBZ Se me parece que ya te ha dado un ejemplo, pero este es solo otro ejemplo de una referencia que se pasa por valor. No pasa por referencia en absoluto. Cambiar el valor de la referencia en el destinatario no lo cambia en la persona que llama. Voto abajo. – EJP

3

de sus referencias:

(1) dice RMI no soporta pase por referencia. Estoy de acuerdo.

(2) dice que RMI no admite parámetros in-out. Estoy de acuerdo.

(3) solo muestra la confusión habitual entre pasar por referencia y pasar referencias por valor. RMI hace lo último, al igual que el resto de Java.

(4) es incorrecto.

(5) es simplemente incoherente. No hay referencia pasada en RMI.

El 'valor por referencias' remoto de RMI no es esencialmente semántico de las 'referencias por valor' locales de Java, aparte de los posibles modos de falla adicionales.

El significado de lo que ha leído es que para las referencias no remotos, RMI argumentos de objetos y los resultados se pasan por valor, a través de serialización de objetos, en lugar de por el argumento de Java método de referencia por valor de paso.

0

En el verdadero sentido de la palabra no, no se puede.

Cuando pasa algo por "referencia" lo que realmente está haciendo es pasar un puntero a una ubicación en la memoria. Esto funciona perfectamente cuando la persona que llama y quien llama son el mismo proceso, tienen acceso exactamente al mismo montón. Pero pasar una referencia de memoria de la computadora A a la computadora B no tiene sentido, A no puede acceder a la memoria Bs *.

Sin embargo, RMI le permite obtener "referencias" a objetos remotos, pero esto no es lo mismo, y tiene que ser solicitado con anticipación, pasar uno de sus objetos al servidor dará como resultado una copia.

Directamente desde la boca de los caballos (http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138781.html#3)

RMI utiliza el objeto estándar de Java mecanismo de serialización para pasar objetos. Los argumentos que son referencias a objetos remotos se pasan como referencias remotas. Si un argumento para un método es un tipo primitivo o un objeto local (no remoto), se pasa una copia profunda al servidor. Los valores devueltos se manejan de la misma manera, pero en la otra dirección. RMI le permite pasar y devolver gráficos de objetos completos para objetos locales y referencias a objetos remotos.

Puede pasar objetos remotos por referencia, pero no puede pasar objetos locales de vuelta al servidor como referencias.

* Técnicamente en algún sistema de memoria compartida distribuida a gran escala, pero dudo que sea de lo que está hablando el OP.

Cuestiones relacionadas