2014-09-02 49 views
0

我期待在移植这个C#库的Java和AndroidJava中的逆变类型参数?

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Client.DotNet

我想将这个接口

public interface IHandle<in T> where T : class 
{ 
    void Handle(T message); 
} 

它需要处理逆变,以便它可以处理类似的消息IHandle<ISomeIntefaceOrBaseClass> etc

图书馆的一个用户可以添加subcribers,并且当一个消息进来时我检查一个处理程序在做什么

subscribers 
    .OfType<IHandle<T>>(); 

这是Java的泛型可能吗,还是有更多'Java方式'这样做?

回答

1

我假设与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

嗯可以有0 - N的处理程序的类型。不能使用Java 8 Streams等等? – Anders 2014-09-02 12:51:45

+0

Java btw中没有内置协变/反变量? – Anders 2014-09-02 12:54:35

+0

做了一些更多的研究,看起来像Covariance可能在Java中,但反变换不是,无赖 – Anders 2014-09-02 12:58:45