2014-08-31 34 views
0

我喜歡有一個java.util.Map,它包含不同的通用類對象。在我的辦案像這樣:具有各種通用類對象的java.util.Map

public interface Handler<s>{ 
public void encode (S data, OutputStream out); 
public S decode (InputStream in, long length); 
} 

我已經實現類,如:

public class SpecializedHandler implements Handler<FirstSpecialItem>{ 
public void encode (SpecialItem data, OutputStream out){ 
    // do something 
} 
public SpecialItem decode(InputStream in, long length){ 
    // do something 
} 
} 

和實現處理程序的類。

對於FirstSpecialItem和SecondSpecialItem存在父類 AbstractSpecialItem

因爲我有很多的使用編碼和解碼已經問題,我結束了以下地圖,這使得使用解碼和編碼如下:

Map<Long, Handler<? super AbstractSpecialItem>> handlers; 
// I can use it as follows 
AbstractSpecialItem item = new FirstSpecializedItem(); 

handlers.get(1L).encode(item,System.out); 
AbstractSpecialItem returnVal = handlers.get(1L).decode(System.in, 100L); 

但是,我不能創建通過添加不同的Handler實現,如:

SpecializedHandler a = new SpecializedHandler(); 
SpecializedSecondHandler b = new SpecializedSecondHandler(); 
Map<Long, Handler<? super AbstractSpecialItem>> handlers = new HashMap<Long,Handler<? super AbstractSpecialItem>>(); 
handlers.put(0L, a); // does not work 
handlers.put(1L, b); // does not work 

Eclipse總是說這些值不適用於Map。 我認爲這種行爲是有效的,並試圖更好地理解泛型和PECS原則(通過網頁和一些書籍瀏覽)。但我仍然不明白,想出一個解決方案。在那裏我有Handler類與他們的特殊泛型類型,並能夠使用方法(編碼,解碼),以及創建一個處理程序的地圖。

+0

用'地圖嘗試>'。 – 2014-08-31 18:18:38

回答

0

它應該工作,如果您使用Map<Long, Handler<? extends AbstractSpecialItem>>而不是Map<Long, Handler<? super AbstractSpecialItem>>。注意延伸而不是超級,爲更詳細的解釋,我建議你看看這個問題的答案:java generics super vs. extends

這裏有一個工作示例:

import java.io.*; 
import java.util.*; 

public class Test { 
    public abstract class A<T extends Closeable> { } 
    public class B<T extends Closeable> extends A<T> { } 
    public class C<T extends Closeable> extends A<T> { } 

    public Map<String, A<? extends Closeable>> map = new HashMap<>(); 
    // instance initializer 
    { 
    map.put("1", new B<InputStream>()); 
    map.put("2", new C<Reader>()); 
    } 
} 
0

在你的情況,你應該使用

Map<Long, Handler<? extends AbstractSpecialItem>> handlers = new HashMap<Long, Main.Handler<? extends AbstractSpecialItem>>(); 

你可以看到超之間的差異,在這裏延伸:Difference between <? super T> and <? extends T> in Java

+0

@Lolo和尼莫,謝謝你的快速回放。是的,這是正確的,但據我所知,如果我使用擴展,我不能再使用編碼方法了。如果我嘗試調用它,Eclipse會顯示以下失敗,如下所示:'handlers.get(1L).encode(item,System.out);''handlers.get(1L).encode((AbstractSpecialItem)item,System .out);' – user2444232 2014-08-31 21:22:02

+0

@Lolo和Nemo,謝謝你的快速回復。是的,但如果我使用擴展,我不能使用編碼方法。如果調用的話,Eclipse會顯示以下失敗:''handlers.get(1L).encode(item,System.out);''handlers.get(1L).encode((AbstractSpecialItem)item,System.out);'_Error:方法encode(capture#2-of?extends AbstractSpecialItem,OutputStream)類型爲Handler 不適用於參數 (AbstractSpecialItem,PrintStream)._使用具體的Item時,它是相同的,例如, _FirstSpecializedItem_。編碼中的項似乎是null類型的。 – user2444232 2014-08-31 21:31:19

+0

我不確定我瞭解你的用例。讓我問你一下;作爲開發者,你需要通過編碼參數。當你從地圖得到一個Handler時,你怎麼知道處理器的類型?您需要知道調用編碼方法的類型(使用FirstSpecialItem或SecondSpecialItem)。 – Nemo 2014-09-03 13:39:15

相關問題