[英]Is it possible to avoid this unchecked cast?
我正在寫參數事件一個簡單的事件系統,該系統采用了Map
從類Set
具有該類作為它們的參數處理的秒。 我的理解是, 我無法通過參數限制來定義鍵和值類型之間的關系,而且我收到了未經檢查的強制警告,將元素從集合中拉出。
這是我目前所擁有的:
public class Manager {
private class Event<T> {
// getSubject(), etc.
}
private interface Handler<T> {
public T handleEvent(Event<T> event, T subject);
}
private final Map<Class<?>, Set<Handler<?>>> handlers = new HashMap<Class<?>, Set<Handler<?>>>();
public <T> void post(final Event<T> event, final T subject) {
final Class<?> type = subject.getClass();
if (this.handlers.containsKey(type)) {
for (Handler<?> handler : this.handlers.get(type)) {
// unchecked cast
((Handler<T>) handler).handleEvent(event, subject);
}
}
}
public <T> void register(final Class<T> type, final Handler<T> handler) {
if (!this.handlers.containsKey(type)) {
this.handlers.put(type, new HashSet<Handler<?>>());
}
this.handlers.get(type).add(handler);
}
}
有可能避免這種未經檢查的演員表嗎? 我的設計中可能有缺陷嗎?
我在這里和Google上都花了很多時間,但是找不到任何可以涵蓋這種安排的東西。
如果事件類本身形成層次結構,則可以通過使用Visitor模式來避免強制轉換。 在Java中這非常麻煩,但是沒有強制轉換。
不幸的是,在這種情況下,您只能執行@SuppressWarnings("unchecked")
。
您的映射聲明中沒有任何內容可以阻止將Class<A>
與Set<Handler<B>>
關聯,因此編譯器無法知道是否是這種情況。 不幸的是,沒有辦法對java.util.Map
任何實現施加這樣的約束。
如果要實現自己的數據結構以允許這種實施(提供Handler<T> getHandler(Class<T> type)
,則最終只會將未經檢查的強制轉換埋入該數據結構中,並保持客戶端代碼的干凈。
附帶說明一下, Map
接口希望將Object
作為get()
, containsKey()
等的參數,因此無論如何,所有通用的東西都會丟失(即使您可以將鍵的通用類型與其鍵之一相關聯)相應的值,這根本不可能)。
我的代碼組織稍有不同, “廣播員代碼”與您的“經理”等效,但是在我的post()代碼中,我的等效於
for (Handler<T> handler : this.handlers.get(type)) {
do stuff ...
}
由於事件參數由T參數化,因此可以將<T>
添加到Handler。 但是我通過猜測和錯誤來做很多看中的泛型東西,YMMV ... :-)
ps您的register()方法應該同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.