2012-04-17 207 views
4

中的方法我想在這裏實現的是由子類來決定是否要將java.lang.String或java.util.HashMap作爲參數傳遞給query()方法。接口只需要聲稱,子類必須實現查詢方法,但我不關心什麼類型的參數的子類希望在通過java泛型類型參數接口

我有一個像接口:

interface A<T>{ 
    public void query(T type); 
} 

兩個子像:

public class B implements A<String> { 
    public void query(String type); 
} 

public class C implements A<HashMap> { 
    public void query(HashMap type); 
} 

然後,我有一個工廠類以產生B或C:

public class AFactory { 
    public static A<?> getType(String type) { 
     if(type.equals("B")){ 
      return new B(); 
     } else if(type.equals("C")) { 
      return new C(); 
     } 
    } 
} 

的想法是,客戶端可以使用該接口,如下而不會對乙依賴性,C等:

A instance = AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

問題我這裏是:日食給我誤差上instance.query的線(a) :

類型A中的方法查詢(capture#2 of?)不適用於參數(String)

我認爲問題在於接口契約不知道查詢應該期待String或HashMap。我只能想到解決這個問題的辦法是,我要投像的結果:

B instance = (B)AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

但是通過這樣做,我會對B的,而不是隻A(接口)的依賴這是一件好事我想在開始時避免。任何想法如何我可以做到這一點,而不依賴於子類(在這種情況下,B和C)。

+0

編譯器查看A實例並說「我需要T,而不是String」,但是你不告訴他T是什麼。盡我所知。 – JMelnik 2012-04-17 13:22:59

+0

graet,gotcha,謝謝@JMelnik – Shengjie 2012-04-17 14:15:50

回答

5

正如歐內斯特所說,你需要投下返回值 - A<String>A<?>更具體。

如果你願意改變工廠方法的簽名,你可以使用仿製藥,以避免投自己:

public static A<T> getType(Class<T> type) { 
    if (type.equals(String.class)) { 
     return new B(); 
    } else if (type.equals(HashMap.class)) { 
     return new C(); 
    } 
} 

然後調用代碼看起來是這樣的:

A<String> instance = AFactory.getType(String.class); 
String a = "test"; 
instance.query(a); 

如果你不能這樣做,那麼getType()的調用者將不得不施放。

+0

+1感謝您的留言,你的回答比我的好:) – 2012-04-17 13:52:15

1

您不必投射到B - 投到A<String>。這會給你query(String),但沒有引入B到源:

@SuppressWarnings("unchecked") 
A<String> instance = (A<String>) AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

我加了註釋@SuppressWarnings,因爲你會得到沒有它「不安全」的警告;你知道警告是虛假的,所以註釋是可以的。