【问题标题】:Why do I get the error "java.lang.String cannot be cast to java.util.List" with the following snippet?为什么我会收到错误“java.lang.String cannot be cast to java.util.List”,下面的代码片段?
【发布时间】:2017-09-07 19:00:42
【问题描述】:

这是一个示例 sn-p,我在其中尝试从 json 对象获取数组列表,但在执行此操作时遇到了类强制转换异常。

public static void main(String args[]) throws Exception {
    List<String> arrayList = new ArrayList<String>();
    arrayList.add("a");
    arrayList.add("b");
    arrayList.add("c");
    arrayList.add("d");
    arrayList.add("e");
    JSONObject json = new JSONObject();
    json.put("raja", "suba");
    json.put("arraylist", arrayList);
    System.out.println("Thus the value of array list is : "+json.get("arraylist"));
    List<String> oldlist = (List<String>) json.get("arraylist");
    System.out.println("Old list contains : "+oldlist);
    System.out.println("The old json contains : "+json.toString());
    String result = json.toString();
    JSONObject json1 = new JSONObject(result);
    System.out.println("The new json value is  : " +json1);
    System.out.println("The value in json for raja is  :" +json1.get("raja"));
    System.out.println("The vlaue of array list is  : "+json1.get("arraylist"));
    List<String> newlist = (List<String>) json1.get("arraylist");
    System.out.println("Thus the value of new list contains : "+newlist);
}

我在获取oldlist 时没有遇到异常,但是在获取newlist 时我遇到了类转换异常。

  1. 为什么数组列表在第一种情况下被视为对象,而在第二种情况下被视为字符串?
  2. json.toString() 究竟做了什么?它是将整个 json 对象转换为字符串,例如将双引号 "" 附加到整个 json 对象,还是将其中的每个对象都转换为字符串?

【问题讨论】:

  • 你必须想办法告诉json值的类型与键arraylist
  • 你是说我们应该得到像“getString”、“getLong”这样的数组列表......是这样的@santosh-patil?
  • 如果您的意图是从 jsonobject 获取列表,则使用以下代码: JSONArray oldlist = json.getJSONArray("arraylist"); System.out.println("旧列表包含:" + oldlist);
  • 由于数组列表不是 JSONArray - 尝试将其作为 json 数组获取将再次导致错误..

标签: java json string arraylist classcastexception


【解决方案1】:

这里的问题是当你这样做时

json.put("arraylist", arrayList);

您明确要求列表序列化。这意味着将执行底层逻辑,以便将与类相关的元数据保存到 JSONObject 中。但是,当您执行 json.toString() 时,此元数据会丢失,您最终会得到一个旧的纯字符串对象。然后,当您尝试在运行时反序列化此 String 时,您会收到 ClassCastException,因为它并不真正知道如何将该 String 转换为列表。

为了回答您的第二个问题,JSONObject.toString() 以 JSON 格式返回对象的字符串表示形式。这意味着如果你有一个 ArrayList,而不是有一个具有 ArrayList.toString() 值的字段,你将有一个具有列表值的数组元素。

【讨论】:

  • 感谢您的回复@Aurasphere。我在这里无法理解您的意思“您明确要求列表序列化。这意味着将执行底层逻辑以便将与类相关的元数据保存到 JSONObject 中”。你能详细解释一下吗?
  • 我没有明白这一点 - 与类相关的哪些元数据将保存在这里 - 它对序列化和反序列化有何帮助?
  • 当然。当您序列化一个类时,无论您使用什么格式(XML、JSON...),您基本上都会获取一个 java 对象并将其转换为一个字符串。当您执行相反的操作时,您将获取此字符串并将其转换回对象的实例。关键是:您的反序列化器类如何知道为您的 JSON 字段选择什么类?当您的 JSON 本身是一个 Java 对象(您的 JSONObject 的情况)时,您可以将此信息存储到 Java 对象中。但是你会在哪里将它存储到一个字符串中?谷歌的 GSON 等一些框架可以做到这一点,但它没有内置到 JSONObject 中。
  • 非常感谢@Aurasphere。你已经解释得很清楚了 - 帮助我理解我的问题:-)
  • 很高兴听到这个消息! :D
猜你喜欢
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 2019-08-29
  • 2018-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多