2015-07-19 58 views
2

我想存儲是一個子類的抽象類的對象,但在這裏說明一個問題:如何將通用參數傳遞給方法?

abstract class Letter { 
    public void store_object(Letter letter) { 
     HashMap<Class<? extends Letter>, ? extends Letter> map = new HashMap<>(); 
     map.put(letter.getClass(), letter); <-- this line throws an error 
    } 
} 
class A extends Letter {} 
class B extends Letter {} 

原因map.put拋出一個錯誤是letter不是一個子類的Letter(它是Letter的直接實例)。

有沒有辦法將方法參數更改爲Letter的通用子類?喜歡的東西:

public void store_object(? extends Letter letter) { 

public void store_object(Object<? extends Letter> letter) { 

的錯誤是:

no suitable method found for put(Class<CAP#1>,NewClass19.Letter) 
    method Map.put(Class<? extends NewClass19.Letter>,CAP#2) is not applicable 
     (argument mismatch; NewClass19.Letter cannot be converted to CAP#2) 
    method AbstractMap.put(Class<? extends NewClass19.Letter>,CAP#2) is not applicable 
     (argument mismatch; NewClass19.Letter cannot be converted to CAP#2) 
    method HashMap.put(Class<? extends NewClass19.Letter>,CAP#2) is not applicable 
     (argument mismatch; NewClass19.Letter cannot be converted to CAP#2) 
    where CAP#1,CAP#2 are fresh type-variables: 
    CAP#1 extends NewClass19.Letter from capture of ? extends NewClass19.Letter 
    CAP#2 extends NewClass19.Letter from capture of ? extends NewClass19.Letter 
+0

你能發表確切的錯誤嗎?而且,你認爲'它是一個Letter的直接實例'是什麼意思?如果「Letter」是抽象的,你怎麼能直接看到它呢? – sstan

+0

發佈錯誤。它涉及到'HashMap'期待''類型的變量?擴展Letter「,但是它得到了一個'Letter'類型的變量。當我說「Letter'的'直接實例,這就是我所指的。 – ryvantage

+0

而不是使用'Map'你可以使用'設置'如果你需要知道某個類型,你可以使用'instanceof' (這組也將接受函的子類)。 – maraca

回答

2

我真的不知道你想在這裏做什麼,但是這樣會讓你的代碼編譯:

abstract class Letter { 
    public <T extends Letter> void store_object(T letter) { 
     HashMap<Class<? extends Letter>, T> map = new HashMap<>(); 
     map.put(letter.getClass(), letter); // <-- this line throws an error 
    } 
} 
class A extends Letter {} 
class B extends Letter {} 

你爲什麼生成每次調用store_object方法時,新的HashMap?你真正的問題是什麼?請閱讀What is the XY problem?

相關:Canonical Java Generics FAQ


順便說一句,Object<Anything>永遠是錯誤的,因爲Object沒有參數。


所以,我看到了你的編輯和FYI這個編譯對我來說:

private static HashMap<Class<? extends Test>, Test> map = new HashMap<>(); 

static void addTest(Test test) { 
    map.put(test.getClass(), test); 
} 

究竟是你的問題?

+0

我問起XY問題的原因是真實情況要複雜得多,而且很難複製。我正在以較小的形式說明問題。這可能令人沮喪(謝謝你的鏈接),但當我提出的問題與我的實際問題接近時,由於複雜性,他們無法回答。 – ryvantage

+0

@ryvantage是否我的版本(指定方法類型參數' void ...')幫助您解決實際問題? – durron597

+0

是的,我知道'Object '是錯的,我只是用它來說明我的頭要去哪裏。有時候這似乎有幫助。 *聳聳肩* – ryvantage

-3

需要改爲<? super Letter>。有一個很好的縮寫,以幫助你記住PECS

如果你想使用泛型參數做:

public <T extends Letter> void method(T arg1) 

**^oops there are no lower bounds (super) on type parameters

編輯:剛纔看到您的編輯。原本我以爲你只是把物體放入某個集合中。靜態映射聲明類型參數是正確的。因爲這兩個的使用和存儲,所以它需要是<Class<? extends>, VCorePanel>

static Map<Class<? extends VCorePanel>, VCorePanel> self...pm; 
public static showPanel(T newInstance){ 
    ... 
    VCorePanel OldInstance = self_panel_map.get(newInstance.getClass()); //use 
    ... 
    self_panel_map.put(newInstace.getClass(), newInstance); //storage 
} 

ps。如果你使用java 8,你可以傳入一個構造函數,而不是使用反射庫。如果你願意的話可以考慮一下。

+0

你爲什麼建議'超級'? – sstan

+0

從收藏的角度來看,它是「消費」這些物品。消費通常意味着你需要超級。 (請參閱上面的鏈接)。例如:你有一個列表。你想放置A類的對象。如果A延伸T,則可以。意義T super A. – Aarjav

0

鑑於B extends AClass<? extends B>Class<? extends A>一個亞型,因此使用通常綁定的Class<? extends Letter>是沒用的。

相反,指定的密鑰類型爲簡單<Class<?>和你的代碼可以編譯(和你其實並不做這個失去任何東西):.