我假设与subscribers.OfType<IHandle<T>>();
你想得到的所有类型的订阅者IHandle<T>
其中T
是消息的类型,对不对?
在Java中,你必须稍微改变你的代码,因为类型擦除你不能提供这样的类型。
假设你有每种类型/类单手柄,你可以做这样的事情:
interface IHandle<T> {
Class<T> getMessageType(); //needed to query the handle for the supported class
void handle(T message);
}
用于创建接口的实现,你有几种选择:
制定实施每类:
class SpecialMessageHandle implements IHandle<SpecialMessage> {
public Class<SpecialMessage> getMessageType() { return SpecialMessage.class; }
public handle(SpecialMessage message) { ... }
}
或者通过类作为参数:
class Handle<T> implements IHandle<T> {
Class<T> messageClass;
public Handle(Class<T> msgClass) { messageClass = msgClass; }
public Class<T> getMessageType() { return messageClass; }
public handle(T message) { ... }
}
然后,您可能会有一个地图消息类来处理类并处理订阅者的类(例如,在Guava Multimap之):
Map<Class<?>, IHandle<?>> handles = ...;
Multimap<IHandle<?>, Subscriber> subscribers = ...;
请注意,我用Class<?>
这里,因为我不知道是否有一个共同的超类或接口的类。如果你有一个共同的超类或接口X
那么你会使用Class<? extends X>
。
另外请注意,我用IHandle<?>
因为在Java中键和值需要同时支持不同的密钥使用相同的通用类型,你无法定义的方式映射,即你不能做Map<Class<T>, IHandle<T>>
其中每个键会是不同的T
,但只允许一个适合关键的值。
添加手柄是这样的:
handles.put(handle.getMessageType(), handle);
查询该地图信息,然后将这样的工作:
IHandle<?> handle = handles.get(message.getClass());
Collection<Subscriber> handleSubscribers = subscribers.get(handle );
需要注意的是,如果你想获得超类的用户也是如此(例如,如果SpecialMessage extends Message
以及你想要订阅Message
的那些人),那么你需要走上类层次结构。
这里是你愿意为一个水平了怎么办:
handles.get(message.getClass().getSuperclass());
for(Class<?> interface : message.getClass().getInterfaces()) {
handles.get(message);
}
嗯可以有0 - N的处理程序的类型。不能使用Java 8 Streams等等? – Anders 2014-09-02 12:51:45
Java btw中没有内置协变/反变量? – Anders 2014-09-02 12:54:35
做了一些更多的研究,看起来像Covariance可能在Java中,但反变换不是,无赖 – Anders 2014-09-02 12:58:45