修改:Java™ Tutorials说
服务器和客户端进行通信并传回信息 所述
和那个RMI
还提供了加载对象类定义的机制 至于传输对象的数据。
我希望“对象的数据”包含服务器对象的变量(例如我的代码中的Test.value
) - 但是我得到的第一条评论表明我可能错了。我原来的问题如下。
我正在尝试访问我通过RMI发送到客户端的远程对象。我只能访问它的方法,但不能访问它的实例变量 - 我得到了接口的字段。我的问题是,一旦我在服务器上实现并实例化一个类,如何在不使用getter的情况下访问其[public]字段?我能够发送没有任何错误或异常的存根,但就像我说的,我无法访问服务器的对象的字段,只能访问接口。以下是我的界面,实现,服务器和客户端的缩写版本。
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface TESTint extends Remote {
double value = -22;
String shortName = "TESTint";
double getValue() throws RemoteException;
}
package test;
import java.rmi.RemoteException;
public class Test implements TESTint {
public double value = -33;
public String shortName = "TestAccount";
public int whole = 1;
public Test(String shortName) {
this.shortName = shortName;
print(shortName);
}
public double getValue() throws RemoteException {
return value;
}
public void print(Object o) {
System.out.println(shortName + ": " + o);
}
}
package test;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RemoteTestMain {
Test test;
public static void main(String[] args) throws InterruptedException {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
new RemoteTestMain();
} // main
public RemoteTestMain() {
test = new Test("Charlie");
Registry registry;
try {
registry = LocateRegistry.createRegistry(1234);
registry.list( ); // will throw an exception if the registry does not already exist
print(test.shortName); // it gets it right here
print(test.value); // it gets it right here
TESTint r = (TESTint) UnicastRemoteObject.exportObject(test, 0);
registry.rebind("DCregistry", r);
print("test bound");
} catch (java.rmi.RemoteException ex) {
print("Remote Exception at Server");
ex.printStackTrace();;
}
}
public static void print(Object o) {
System.out.println("Server: " + o);
}
}
package test;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
TESTint test;
public static void main(String[] args) {
try {
new Client();
} catch (RemoteException e) {
e.printStackTrace();
}
} // main
private void init(int account) {
print("INITiating Account " + account);
try {
Registry registry = LocateRegistry.getRegistry(1234);
test = (TESTint) registry.lookup("DCregistry");
} catch (Exception e) {
System.err.println("RMI exception:");
e.printStackTrace();
}
print("Short name : " + test.shortName);
print("value: " + test.value);
try {
print("Value through getter is " + test.getValue());
} catch (RemoteException e) {
print("Could not get equity");
e.printStackTrace();
}
} // init(int account)
public Client() throws RemoteException {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
init(2);
}
private static void print(Object o) {
System.out.println("GUI: " + o);
}
}
P.S。在上面的客户端代码中,test.shortName
带有下划线,Eclipse表示The static field TESTint.shortName should be accessed in a static way
。我知道客户端不承认实现,只识别接口 - 但有没有办法访问测试的字段,而不仅仅是它的方法?我的原始代码中有很多字段,如果可能的话,我不想为每一个编写getter。
答案 0 :(得分:1)
RMI
代表Remote Method Invocation
,这意味着您可以远程执行对象的方法。该方法的实现驻留在远程系统中。您永远不能访问远程系统中存在的实现类的实例变量,即使它们是公共的。您只能执行由Inteface公开的公共方法。因此,如果要访问变量,则需要在Inteface和实现类中添加public gettter方法。