2011-09-26 192 views
2

如何獲取一個參數化的Class對象作爲方法參數?泛型:創建參數化類參數

class A<T> 
{ 
    public A(Class<T> c) 
    { 
    } 

    void main() 
    { 
     A<String> a1 = new A<String>(String.class);  // OK 
     A<List<String>> a2 = new A<List<String>>(List<String>.class); // error 
     A<List<String>> a3 = new A<List<String>>(Class<List<String>>); // error 
    } 
} 

爲什麼我要這樣做,你可能會問?我有一個參數化類,其類型是另一個參數化類,其構造函數要求其他類類型作爲參數。我知道運行時類沒有關於它們的類型參數的信息,但是這不應該阻止我在編譯時這樣做。看來我應該能夠指定一個類型,例如List<String>.class。是否有另一種語法來做到這一點?

這裏是我的實際使用情況:

public class Bunch<B> 
{ 
    Class<B> type; 

    public Bunch(Class<B> type) 
    { 
     this.type = type; 
    } 

    public static class MyBunch<M> extends Bunch<List<M>> 
    { 
     Class<M> individualType; 

     // This constructor has redundant information. 
     public MyBunch(Class<M> individualType, Class<List<M>> listType) 
     { 
      super(listType); 
      this.individualType = individualType; 
     } 

     // I would prefer this constructor. 
     public MyBunch(Class<M> individualType) 
     { 
      super(/* What do I put here? */); 
      this.individualType = individualType; 
     } 
    } 
} 

這可能嗎?

+1

看看谷歌Gson的'TypeToken' http://google-gson.googlecode。 COM/SVN /中繼/ GSON /文檔/ javadocs中/ COM /谷歌/ GSON /反射/ TypeToken.html。它是開源的,它解決了你遇到的同樣的問題。 – BalusC

+0

[Java通用函數:如何返回泛型類型]的可能重複(http://stackoverflow.com/questions/1959022/java-generic-function-how-to-return-generic-type) – BalusC

+0

謝謝BalusC。首先,我很安慰我不會錯過簡單的事情。但是我還沒有準備好這樣做,因爲在我的應用程序中處理** Type **而不是** Class ** es看起來很困難。 –

回答

0

剛剛施放如何?

super((Class<List<M>>)List.class); 

類文字是不會有你想要的類型參數。

0

記住你不會在運行時得到一個List作爲類,正確的做法可能是使用TypeToken作爲BalusC告訴你的。沒有TypeToken,你無法投射到列表中,但你可以這樣創造的東西:

public static class MyBunch2<List_M extends List<M>, M> extends Bunch<List_M> 
{ 
    Class<M> individualType; 

    @SuppressWarnings("unchecked") 
     public MyBunch2(Class<M> individualType) 
    { 
     super((Class<List_M>) List.class); 
     this.individualType = individualType; 
    } 
} 

由於List_M extends List<M>這並不像類型安全,你可能希望,但也許是不夠好。創建一個實例將是寫作

MyBunch2<List<String>, String> a = new MyBunch2<List<String>, String>(String.class); 

醜陋,但你可以用一個工廠方法改進

public static <M2> MyBunch2<List<M2>, M2> of(Class<M2> individualType){ 
    return new MyBunch2<List<M2>, M2>(individualType); 
} 

,然後寫

MyBunch2<List<String>, String> b = MyBunch2.of(String.class); 

如果您正在使用Eclipse,代碼輔助將幫助你寫出醜類MyBunch2,字符串>

當然,在運行時,this.ty pe將是java.util.List,而不是java.util.List 爲了正確使用,請輸入TypeToken。

--- ---延續

你甚至可以讓其他類

public static class MyBunch3<M> extends MyBunch2<List<M>, M> 
{ 
     public MyBunch3(Class<M> individualType) { 
      super(individualType); 
     } 
} 

然後創建實例作爲

MyBunch3<String> c = new MyBunch3<String>(String.class); 

必須有辦法做到這一點,在短短一類......但我不知道它