2011-09-26 158 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); 

必须有办法做到这一点,在短短一类......但我不知道它