将类型参数作为类型参数的类传递给Java中的泛型方法
我想将具有类型参数(ArrayList<SomeClass>
例如)的类作为类型参数传递给泛型方法。
假设我有一个方法:
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
,但是泛型类型的添加使其在语法上不再有效,并且我想不出解决方法。
唯一的直接解决方案是这样的事情(看起来很愚蠢):
getGenericObjectFromJson(jsonString, new ArrayList<User>().getClass())
但是,无论如何,我们最终都会丢失通用类型,而只是返回未知类型的ArrayList(尽管可以强制转换)。另外,不必要地实例化一个对象。
到目前为止,我唯一的解决方案是将该方法包装在一个包含可实例化的泛型类型参数的类中,如下所示:
public class JsonDeserializer<T>...
在这种情况下,该getGenericObjectFromJson
方法将使用该类的泛型类型。
最终,我很好奇为什么我不能传递带有类型参数的类,以及是否有一种方法可以完成我尝试做的事情。
与往常一样,请让我知道这个问题是否有任何问题。
回答:
实际上,在Java中使用一些“技巧”是可能的。不要屈服于C#狂热分子的压力!(j / k)
“技巧”是创建一个扩展通用类型的类,并Type
通过.getGenericSuperclass()
或返回的值访问父类的类型参数的值.getGenericInterfaces()
。
这很麻烦。为了简化我们的生活,Google已经为我们编写了大部分无聊的代码,并通过Guava提供了该代码。
检查 课程,它确实满足您的要求。例如:
TypeToken<List<String>> stringListTok = new TypeToken<List<String>>() {};
然后,您绕过a TypeToken<T>
而不是a就Class<T>
这样。它为您提供了对T表示的类型进行反射的方法。
它在内部所做的只是调用.getClass().getGenericSuperclass()
(或...Interfaces()
),然后从Type
进行一些丑陋的转换,ParameterizedType
并从那里检索所有信息(.getActualTypeArguments()
,等等)。
最后,如果您想对Dependency Injection做一些类似的事情(即,假设您需要Class<T>
在类的构造函数中注入a
,或者想获取某个参数化接口的实例,则该实例中的实例应取决于类型参数) ),Google
Guice(来自Google的DI容器)具有一种非常相似的机制来解决该问题,称为TypeLiteral
。幕后的用法和代码与TypeToken
Guava
几乎相同。在这里检查:
以上是 将类型参数作为类型参数的类传递给Java中的泛型方法 的全部内容, 来源链接: utcz.com/qa/419480.html