Java 了解GSON';s的TypeToken包含一个列表?

Java 了解GSON';s的TypeToken包含一个列表?,java,json,gson,Java,Json,Gson,我使用GSON在Java中解析json。当我想从json字符串中获取整数列表时,我的代码可能如下所示: Type type = new TypeToken<List<Integer>>(){}.getType(); List<Integer> result = null; try { result = new Gson().fromJson(jsonStringGoesHere, type); } catch

我使用GSON在Java中解析json。当我想从json字符串中获取整数列表时,我的代码可能如下所示:

    Type type = new TypeToken<List<Integer>>(){}.getType();

    List<Integer> result = null;
    try {
        result = new Gson().fromJson(jsonStringGoesHere, type);
    } catch (JsonSyntaxException e) {
        e.printStackTrace();
    }
但这会抛出
java.lang.ClassNotFoundException:java.util.List


有什么想法可以让它工作吗?

在Java中,集合的泛型部分在编译时起作用,因此它在运行时不可用,这就是您得到该异常的原因。因此,如果您想使用反射创建Collection类型的类,那么您必须删除泛型部分

另外,列表设置映射是不能直接实例化的接口。因此,为了创建一个对象,您必须使用它们的一个实现,如ArrayListLinkedList

我的尝试是检查
if(键入instanceof Collection)
——但返回
false

这不起作用,因为
类型
集合
不是“可相互转换”的,存在于不同的层次结构中

我的下一次尝试是使用
type.getTypeName()
返回字符串
java.util.List

这也不行
Class.forName
通过完全限定的名称返回现有的
Class
实例(简单地说,是由
类路径
中的
.Class
文件表示的内容),但决不是参数化类(类是不可参数化的,但可以是带有参数化超类的子类——这就是类型标记下的内容)。因此,
Class.forName(“java.util.List”)
有意义,但
Class.forName(“java.util.List”)
没有意义

请注意,
Type
可以表示一个类型,而
TypeToken
可以用于此目的。只要看看它是如何声明的,您就会更好地理解它。更重要的是,它的子接口
parameteredType
可以保存类型参数,这可以由
TypeToken
或cons生成手动构造(像往常一样--只需查看接口声明)。
TypeToken
s通常使用匿名基类参数化从中获取类型参数,这就是为什么它们被设计成这样:很好的编译时支持+Google Guava、Jackson和Spring框架中有类似的技术(但是如果Java能够支持类似于
Java.util.List.type
的东西来获取参数化类型实例,那就太好了)。在以后的Gson版本中,您甚至可以使用
TypeToken.getParameterized(…)
,这只是创建参数化类型的一种方便方法

您要查找的是“class instanceof”或“a-subclass-of”(如果可以这样称呼):
class.isAssignableFrom(…)
。此实例方法检查一个类是相同的还是另一个类的子类。例如

SuperClass.class.isAssignableFrom(SubClass.class)
始终返回
true
。因此,您只需这样检查:

    Type type = new TypeToken<List<Integer>>(){}.getType();

    List<Integer> result = null;
    try {
        result = new Gson().fromJson(jsonStringGoesHere, type);
    } catch (JsonSyntaxException e) {
        e.printStackTrace();
    }
final Type=new-TypeToken(){
}.getType();
final-TypeToken-TypeToken=TypeToken.get(type);
System.out.println(List.class.isAssignableFrom(typeToken.getRawType());
甚至更短:

final-TypeToken-TypeToken=new-TypeToken(){
};
System.out.println(List.class.isAssignableFrom(typeToken.getRawType());
两者都返回
true
。请注意,类型标记通过
getRawType()
返回
Class
实例,但不返回
getType()
,因为后者可能不代表类(例如,
Collection.Class.isAssignableFrom(List)
return?)


此外,您还可以将类型标记及其类型提取到
静态final
字段中,因为它们是不可变的值,不应在运行时更改。

将列表更改为
type type=new中的ArrayListTypeToken@Ibrahim这样做,
result
仍然为null,
instanceof
仍然返回false并创建一个新instance()仍然抛出
java.lang.ClassNotFoundException:java.util.ArrayList
。如果您将代码示例的输出放在这里,那将是一件非常好的事情。