2014-09-02 50 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