在Java中通过types参数的类作为generics方法的types参数

问题总结:我想通过一个types参数的类(例如ArrayList<SomeClass> )作为typesparameter passing给generics方法。

假设我有一个方法:

  public static <T> T getGenericObjectFromJson(String json, Class<T> genericType){ // details unimportant, basically returns an object of specified type return JsonParser.fromJson(json, genericType); } 

当然,这种方法对于任何一种类都是完美的。 我可以这样调用方法,例如:

 getGenericObjectFromJson(jsonString, User.class) 

问题:我发现我不能这样做:

 getGenericObjectFromJson(jsonString, ArrayList<User>.class) 

在句法上,这显然是无效的。 但是,我不确定我会如何完成这样的事情。 当然,我可以通过ArrayList.class ,但是通用types的添加使得它不再是语法上有效的,我想不出一个办法。

唯一的直接解决scheme就是这样(这看起来相当愚蠢):

 getGenericObjectFromJson(jsonString, new ArrayList<User>().getClass()) 

然而,我们最终失去了genericstypes,只是取回一个未知types的ArrayList(尽pipe它可以被强制转换)。 另外,不必要的实例化一个对象。

到目前为止,我唯一的解决scheme是将该方法包装在一个包含可以实例化的genericstypes参数的类中,如下所示:

 public class JsonDeserializer<T>... 

在这种情况下, getGenericObjectFromJson方法将使用该类的genericstypes。

问题:最后,我很好奇为什么我不能通过一个types参数的类,以及是否有一种方法来实现我想要做的。

一如往常,让我知道这个问题是否有问题。

这实际上可能在Java中使用一些“技巧”。 不要屈服于C#狂热者的压力! (J / K)

“技巧”是创build一个扩展generics的类,并通过.getGenericSuperclass().getGenericInterfaces()返回的Type.getGenericSuperclass()父类的types参数的值。

这很麻烦。 为了简化我们的生活,Google已经为我们编写了大部分代码的无聊部分,并通过Guava提供。

检查TypeToken类,这正是你想要的。 例如:

 TypeToken<List<String>> stringListTok = new TypeToken<List<String>>() {}; 

然后你传递一个TypeToken<T>而不是一个Class<T> ,就这些了。 它为您提供了用T表示的types的reflection方法。

这是在内部做的只是简单地调用.getClass().getGenericSuperclass() (或...Interfaces() ),然后从TypeParameterizedType Type一些丑陋转换,并从那里检索所有信息( .getActualTypeArguments()等)。

最后,如果你想做类似的dependency injection(例如,假设你需要在一个Class<T>的构造函数中注入一个Class<T> ,或者你想获得一个实例应该依赖的参数化接口的实例在types参数上),Google Guice(来自Google的DI容器)有一个非常类似的机制来解决这个问题,称为TypeLiteral 。 幕后的使用和代码几乎和Guava的TypeToken一样。 在这里检查: TypeLiteral