假设我有一个接口,它描述了可能的请求处理程序,这些处理程序可以在客户端存储的某些客户端会话状态的上下文中为客户端请求的操作提供服务:
public interface RequestHandler<State> {
// Perform action in the context of currentState and return updated state
public State request(State currentState, String action);
}
为了便于实现 RequestHandlers,我添加了泛型类型State
,它封装了所有需要的客户端会话数据。
现在,一个简单的客户端可能如下所示:
public class Client {
private final RequestHandler<?> handler;
private Object state;
Client(RequestHandler<?> handler) {
// Initialize the RequestHandler to use for "go"-requests
this.handler = handler;
// Initialize our client state to "null"
this.state = null;
}
public void go() {
// Execute "go"-request in current state and update state
state = handler.request(state, "go"); // <= this is an error (see below)
}
}
在创建过程中,它会被提供一个RequestHandler
,然后它会使用它来执行“go”-requests。它还在私有state
变量中管理其当前会话状态的存储。
现在,由于我的客户不需要担心会话状态在内部实际上是什么样子,我想使用RequestHandler<?>
如图所示。但是,不幸的是,这给了我一个错误state = handler.request...
:
RequestHandler 类型中的方法 request(capture#3-of ?, String) 不适用于参数 (Object, String)
将违规行更改为:
state = ((RequestHandler<Object>) handler).request(state, "go");
(这会将错误变成“未经检查的演员表”警告)
显然,这样我就可以对我的state
-object 进行类型检查,但是如果Client
唯一将它设置为null
或由 . 返回的东西RequestHandler
,应该没有问题,对吧?
我知道我也可以参数化Client
,然后Client<State>
在State
任何地方使用。但我宁愿避免这种情况,因为(在我看来)在这种情况下它只是自重,必须在任何实例化或使用 a 的地方随身携带......Object
?
Client
没有办法投射state
到(?)
,对吧?
更新:
如果一切都发生在单个方法而不是类中,那么这个问题有一个很好的解决方案:
public <State> void go(RequestHandler<State> handler) {
State state = null;
state = handler.request(state, "go");
state = handler.request(state, "go again");
state = handler.request(state, "go one more time");
}
这样,我可以在任何地方调用,而不必总是指定State
实际是什么。但是整个类没有等效的构造(一些推断的通用参数)吗?