Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSON反序列化:java.lang.Double不能强制转换为java.lang.Long_Java_Json_Gson - Fatal编程技术网

JSON反序列化:java.lang.Double不能强制转换为java.lang.Long

JSON反序列化:java.lang.Double不能强制转换为java.lang.Long,java,json,gson,Java,Json,Gson,以下内容在控制台上工作并打印42: long l = (new Gson()).fromJson("42", Long.class); System.out.printf("[%d]\n", l); 以下内容也适用并打印相同内容: final Type TYPE = new TypeToken<Long>() {}.getType(); long l = (new Gson()).fromJson("42", TYPE); …在源中标记的行处 完整轨迹非常浅,只有这一行: [

以下内容在控制台上工作并打印42:

long l = (new Gson()).fromJson("42", Long.class);
System.out.printf("[%d]\n", l);
以下内容也适用并打印相同内容:

final Type TYPE = new TypeToken<Long>() {}.getType();
long l = (new Gson()).fromJson("42", TYPE); 
…在源中标记的行处

完整轨迹非常浅,只有这一行:

 [java] Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Long
 [java]     at FooMain.main(FooMain.java:18)
为什么会发生这种情况,为什么在编译时没有检测到问题

我已经用gson 2.8.0测试过了

我认为这可能与泛型类型信息在运行时被擦除有关,因此可能无法在运行时基于提供的泛型类型构造
TypeToken

经过进一步的实验,我得到的异常与我所做的相同:

private static Object fromJSON(String json) {
    final Type TYPE = new TypeToken<Object>() {}.getType();
    Object rv = (new Gson()).fromJson(json, TYPE);
    return rv;
}

public static void main(String args[]) throws Exception {
    long l = (long) fromJSON("42");
}
私有静态对象fromJSON(字符串json){
final-Type=new-TypeToken(){}.getType();
Object rv=(new Gson()).fromJson(json,类型);
返回rv;
}
公共静态void main(字符串args[])引发异常{
long l=(long)fromJSON(“42”);
}
…以上在运行时生成完全相同的跟踪,这与类型擦除解释一致。所以我想我们只能等到Java9了。

简短的回答是“类型擦除”

较长的答案是,代码的通用版本——
newtypetoken()
call——不会记录每个调用的不同类型值。
T
的值仅在编译时使用,在运行时不可用,并且只有一个运行时版本的代码必须处理可以传递给它的每个值


这样做的结果是Gson最终试图解析类型为“
T
”的值,并且无法知道
T
实际上是
长的。因此,它根据内容进行猜测,内容是一个数字,它与数字类型一起使用,具有最广泛的可能值范围-
Double

捕获异常并打印堆栈跟踪-可能有用我认为您关于类型擦除的想法可能非常正确:/
 [java] Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Long
 [java]     at FooMain.main(FooMain.java:18)
private static Object fromJSON(String json) {
    final Type TYPE = new TypeToken<Object>() {}.getType();
    Object rv = (new Gson()).fromJson(json, TYPE);
    return rv;
}

public static void main(String args[]) throws Exception {
    long l = (long) fromJSON("42");
}