在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()
),然后从Type
到ParameterizedType
Type
一些丑陋转换,并从那里检索所有信息( .getActualTypeArguments()
等)。
最后,如果你想做类似的dependency injection(例如,假设你需要在一个Class<T>
的构造函数中注入一个Class<T>
,或者你想获得一个实例应该依赖的参数化接口的实例在types参数上),Google Guice(来自Google的DI容器)有一个非常类似的机制来解决这个问题,称为TypeLiteral
。 幕后的使用和代码几乎和Guava的TypeToken
一样。 在这里检查: TypeLiteral