比方說,我有一個描述可以服務由客戶端在某些客戶端會話狀態的情況下請求的操作可能請求處理程序的接口,由客戶端存儲:處理<?>型
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