繁体   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