在Java中为泛型方法传递类型参数为类型参数的类

在Java中为泛型方法传递类型参数为类型参数的类,java,class,generics,Java,Class,Generics,问题摘要: 我想将带有类型参数的类(例如ArrayList)作为类型参数传递给泛型方法 假设我有一个方法: public static <T> T getGenericObjectFromJson(String json, Class<T> genericType){ // details unimportant, basically returns an object of specified type return JsonPa

问题摘要: 我想将带有类型参数的类(例如
ArrayList
)作为类型参数传递给泛型方法

假设我有一个方法:

    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, ArrayList<User>.class)
然而,无论如何,我们最终都会丢失泛型类型,只会返回一个未知类型的ArrayList(尽管它可以强制转换)。另外,不必要地实例化一个对象

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

public class JsonDeserializer<T>...
公共类JsonDeserializer。。。
在这种情况下,
getGenericObjectFromJson
方法将使用类的泛型类型

问题:归根结底,我很好奇为什么我不能传递带有类型参数的类,以及是否有办法完成我试图完成的任务


和往常一样,如果这个问题有任何问题,请告诉我。

这在Java中实际上是可能的,使用一些“技巧”。不要屈服于狂热分子的压力!(j/k)

“诀窍”是创建一个扩展泛型类型的类,并通过
.getGenericSuperclass()
.getGenericInterfaces()
返回的
type
访问父类的type参数值

这相当麻烦。为了简化我们的生活,谷歌已经为我们编写了大部分枯燥的代码,并通过Guava提供

检查类,它完全满足您的需要。例如:

getGenericObjectFromJson(jsonString, User.class)
TypeToken<List<String>> stringListTok = new TypeToken<List<String>>() {};
TypeToken stringListTok=新的TypeToken(){};
然后传递一个
TypeToken
,而不是
,就这样。它为您提供了对T表示的类型进行反射的方法

这在内部只需调用
.getClass().getGenericSuperclass()
(或
…Interfaces()
),然后从
类型
参数化类型
进行一些丑陋的强制转换,并从中检索所有信息(
.getActualTypeArguments()
,等等)


最后,如果您想使用依赖项注入做类似的事情(例如,假设您需要在类的构造函数上注入一个
,或者您想获得某个参数化接口的实例,其中的实例应该依赖于类型参数),Google Guice(Google提供的DI容器)有一个非常类似的机制来解决这个问题,称为
TypeLiteral
。幕后的使用和代码与Guava的
TypeToken
几乎相同。检查这里:

由于类型擦除,我认为这是不可能的。Java泛型是编译时构造,在运行时不存在,因此不存在表示构造泛型类型的
对象。由于“类型擦除”(java在编译时就是这样做的)的原因,您无法通过删除泛型类型信息来实现这一点。将其重新编码为
getGenericarArrayListFromJSON(jsonString,User.class)
?这可能是您能做到的最好的了。实际上,在Java中这是可能的。泛型类型信息在运行时不会完全丢失——您可以访问父类或接口上的泛型类型信息!请检查下面我的答案。@asgs它已经过时了,但是的,这可能就是我的意思。将更新以避免混淆任何人。哇,这真是太棒了。有趣的是,我实际上在使用google Gson的库,它使用(或至少包含部分)番石榴,但是我显然没有完全理解TypeToken是如何工作的。非常感谢,非常有用的信息。有人能详细介绍一下第一种方法吗。好了,您不能在java中扩展泛型类型。@Kedarnath,
class a{}类B扩展了a{}
-->这绝对没问题。这就是你说的吗?你能提供一个你声称不可能的例子吗?
TypeToken<List<String>> stringListTok = new TypeToken<List<String>>() {};