确定序列化对象的类型

时间:2011-03-28 00:27:16

标签: java serialization

我需要通过套接字发送消息(来自用户的请求到引擎,以及从引擎到用户的响应)。所以流程基本上是

       +--------+ serialized  request +--------+      
       | Server | <==== network ====> | Client | 
       +--------+ serialized response +--------+      
           ^                              ^
           | request/response             | mouse/keyclicks
           |    object                    |
           v                              v
       +--------+                     +--------+
       | Engine |                     |  User  |
       +--------+                     +--------+

现在,重新发明轮子才有意义。我正在处理双方的Java,所以我计划使用像这样的对象:

/**
 * A Client makes a Request.
 */
abstract class UserRequest implements Serializable {
    /**
     * The engine will call request.engineCallback(this);
     * This will tell the Engine what the request is, at which point
     * the Engine will determine its response.
     */
    abstract EngineResponse engineCallback(Engine engine);
}

/**
 * The Engine has calculated a Response.
 */
abstract class EngineResponse implements Serializable {
    /**
     * The User will call response.userCallback(this);
     * This tells the User what the Engine thought of its request,
     * and what happened as a result.
     */
     abstract void userCallback(User user);
}

我没有关注的是,在我的服务器和客户端套接字中,我如何知道请求和响应的子类是什么?我看到像

这样的情况
Object request = in.readObject();

// now what? How do I know what to cast it to?

// Can I just cast it like
UserRequest request = (UserRequest)(in.readObject());
engine.addToRequestQueue(request); // let it take care of implementation details?

我的第一个想法是通过字符串传递所有内容,但是当Java提供序列化时,这看起来有点傻。但是我怎样才能确定我知道哪个班级遇到了什么?就此而言,我是否需要知道,只要我只将UserRequest的死者发送到服务器并将EngineResponse发送给客户端?

2 个答案:

答案 0 :(得分:6)

只需使用提供的instanceof关键字:

Object o = in.readObject();

if (o instanceof SomeUserRequest)
{
  SomeUserRequest sur = (SomeUserRequest)o;
  ..
}
else if (o instanceof OtherUserRequest)
{
  ..
}

答案 1 :(得分:0)

为使您的协议可用于简单序列化,您需要在连接的两端提供所有可用的类。

您的engineCallback()方法将在服务器上执行,而不是对客户端的真正回调。

如果你想要更多(比如在另一方调用方法,并传递另一方尚未提供的类),你可能想看看RMI(远程方法调用)。它基于协议的Java序列化,但添加了方法调用以及将未知类传递到另一端以在那里执行的能力。