我正在使用此库:https://github.com/jdereg/json-io
这是我要重现该错误的简化示例:
import com.cedarsoftware.util.io.JsonReader;
Map args = new HashMap();
args.put(JsonReader.USE_MAPS, true);
List<String> a = (List<String>)JsonReader.jsonToJava("[\"1.1\",\"1.2\"]", args);
运行时,抛出:
java.lang.ClassCastException:类[Ljava.lang.Object;不能强制转换为类java.util.List([Ljava.lang.Object;和java.util.List在加载程序'bootstrap'的模块java.base中)
或者,args
也可以省去(删除中间两行,并删除args
的{{1}}自变量)。
阅读词典/地图效果很好,例如,此代码按预期输出“ example”:
jsonToJava
只有数组我无法弄清楚如何读取。我已经找到的关于该库的文档非常简洁,并且没有显示此示例。跟踪源代码以查看其应为哪种对象,最后得到一个名为readArray的函数,该函数在内部使用ArrayList:https://github.com/jdereg/json-io/blob/master/src/main/java/com/cedarsoftware/util/io/JsonParser.java#L280。看来我正在做的事情应该可以转换为List(为了确定,我也尝试过ArrayList)。
答案 0 :(得分:1)
java.lang.ClassCastException:类[Ljava.lang.Object;不能转换为类java.util.List
请注意,[Ljava.lang.Object
代表对象数组的数组类型,因此它是Object[]
。由于JSON数组可以包含任何内容,即字符串,布尔值,数字,对象或数组,并且任何JSON解析器可以任意组合使用3个选项:
Object
作为数组的元素类型。然后,您的情况将导致Object[]
。String[]
结果。如果该数组包含字符串以外的任何内容,则很可能会失败。String
的字符串)。但是,API无法反映这一点,因为编译器不知道json在运行时将包含什么。因此,API只能使用前两个选项(在许多类似Jackon或Gson的库中都存在),因此用户将不得不强制转换数组或元素本身,在这种情况下,获得的收益很小。如此复杂的解析器。现在您可能会问为什么解析器返回Object[]
而不是List<Object>
。这是该库的设计者做出的决定,我只能猜测原因是什么。但是,json本身仅知道数组,因此,如果未提供其他类型信息,则逻辑后果是也将使用Java数组。
答案 1 :(得分:1)
为扩展Thomas的出色答案,以下是人类可读json的解决方案:
将对象列表转换为json:
public String toJSONList(List<Foo> fooList) {
Map<String, Object> args = new HashMap<>();
args.put(JsonWriter.PRETTY_PRINT, true); // just to make sure it looks good
args.put(JsonWriter.TYPE, false); //disable ugly @type properties
return JsonWriter.objectToJson(fooList, args);
}
它生成具有列表的可读性很好的json:
[
{
"id":100,
"name":"John"
},
{
"id":101,
"name":"Tirion"
}
]
将上述json转换回列表
public List<Foo> fromJSONList(String json) {
Map<String, Object> args = new HashMap<>();
args.put(JsonReader.USE_MAPS, true);
JsonReader jsonReader = new JsonReader();
List<Foo> result = new ArrayList<>();
Object[] array = (Object[])JsonReader.jsonToJava(json, args);
for (int i=0; i<array.length; i++) {
//we need to tell what is the type (remember that we have removed it above?)
((Map)array[i]).put("@type", "com.something.model.Foo");
Foo foo =(Foo)jsonReader.jsonObjectsToJava((JsonObject) array[i]);
result.add(foo);
}
return result;
}