簡體   English   中英

有可能避免這種未經檢查的演員表嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM