比方说,我有一个描述可以服务由客户端在某些客户端会话状态的情况下请求的操作可能请求处理程序的接口,由客户端存储:处理<?>型
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
,它后来用来执行“走出去” -REQUESTS。它还管理其私有的state
变量中当前会话状态的存储。
现在,由于我的客户不需要担心会话状态在内部看起来像什么样,我想使用RequestHandler<?>
,如图所示。但不幸的是,这给了我在state = handler.request...
行错误:(?捕获#3的,字符串)
的方法请求的类型 RequestHandler不适用于参数 (对象,字符串)
有只改变了违规行的一个问题:
state = ((RequestHandler<Object>) handler).request(state, "go");
(这将会错误为“未投” -warning)
显然,这样我松散型检查我的state
-object,但如果Client
永远只能将它设置为null
或由RequestHandler
返回的东西,应该没有问题吧?
我知道我也可以只参数Client
为Client<State>
以及再利用State
代替Object
和?
无处不在。但我宁愿避免这一点,因为它(在我看来)只是在这种情况下的自重,将不得不随身携带,无论Client
实例化或使用...
有没有办法投state
到(?)
,对吧?
UPDATE:
有一个漂亮的解决了这个问题,如果一切都被一个方法里面发生的事情,而不是一类:
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
实际上是。但是对于整个类没有等价的构造(一些推断的泛型论证)在那里?
使该投会让你失去你的类型安全,因为你说。你为什么试图在这里使用泛型?这听起来像请求只接受'国家'并返回'国家'。有另外一种情况,RequestHandler将被用于其他事情吗? – nickrak
@nickrak但是它不可能导致运行时异常,无论使用哪个参数'RequestHandler'实际指定,正确? (当然,只有当我的'Client'决定将它自己的非法内容保存在'state'中时) –
如果你传递了非State的东西,会导致ClassCastException。这不会在编译时被捕获,因为客户端没有意识到类型限制。 – nickrak