【问题标题】:How to add ArrayList<String> to JSON Array - keeping type safety in mind如何将 ArrayList<String> 添加到 JSON 数组 - 牢记类型安全
【发布时间】:2013-08-22 12:19:59
【问题描述】:

Eclipse 显示了一个类型安全警告,我几乎尝试了所有方法来消除它(当然可以选择抑制它),但不幸的是我没有成功。
你知道我必须如何更改我的代码,以便不再有类型安全警告。还是@SuppressWarnings("unchecked") 是唯一的方法?

ArrayList<String> arrayList= (ArrayList<String>) Classname.getArrayList();      
JSONArray obj = new JSONArray();
obj.addAll(arrayList); 

在最后一行显示以下类型安全警告:

类型安全: addAll(Collection) 方法属于原始类型 ArrayList。对泛型 ArrayList 的引用应该参数化

JSONArray 来自org.json.simple.JSONArray。您会推荐其他套餐吗?

【问题讨论】:

  • 抱歉,您无能为力,因为问题在于 JSONArray 的实现,它不使用泛型。
  • 你会推荐使用 JSONArray 的另一个实现吗?换句话说,要使用 org.json.simple.JSONArray 以外的其他包或更好地添加 @SuppressWarnings('unchecked')?
  • 请阅读我的回答。

标签: java json arraylist type-safety


【解决方案1】:

如果你想使用 json 去这个库,这个库有很好的支持https://code.google.com/p/google-gson/。

这是一个例子:

Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

(Serialization)
String json = gson.toJson(ints); ==> json is [1,2,3,4,5]

谢谢

【讨论】:

    【解决方案2】:

    org.json 和 org.json.simple JSON 解析器使用原始类型的集合。如果您正在寻找良好的Generics 支持,请尝试Google Gson。以下是使用 Gson 序列化通用 ArrayList 的方法:

    Gson gson = new Gson();
    
    ArrayList<String> arrayList= (ArrayList<String>) ClassName.getArrayList();
    
    // Serializing to a JSON element node
    JsonElement jsonElement = gson.toJsonTree(arrayList);
    System.out.println(jsonElement.isJsonArray()); // true
    
    // Or, directly to JSON string
    String json = gson.toJson(arrayList);
    System.out.println(json);
    

    以下是您如何反序列化具有完整 Generics 的相同 JSON 字符串:

    Type type = new TypeToken<ArrayList<String>>(){}.getType();
    ArrayList<String> arrayList = gson.fromJson(json, type);
    

    【讨论】:

      【解决方案3】:

      您的问题的简短答案是您必须压制它才能让它消失。问题不在于您使用 addAll 方法放置了什么,这是因为如果未提供类型,JSONArray 无法保证类型安全。

      JSONArray 继承了一个非参数化的 ArrayList,addAll 方法定义为:

      public boolean addAll(java.util.Collection<? extends E> es)
      

      在不提供类型参数的情况下,E 回退到 Object,这使得 addAll 方法成为一种可以在现有集合之上添加包含 ANYTHING 的集合的方法。因此,您可以这样做:

      List<Dog> dogs = new ArrayList<Dog>();
      dogs.add(new Chiwawa());
      
      List<Car> cars = new ArrayList<Car>();
      cars.add(new BMW());
      
      JSONArray jsonArray = new JSONArray();
      jsonArray.addAll(dogs);
      jsonArray.addAll(cars);
      

      Dogs 和 Cars 一起添加到同一个 JSONArray (ArrayList) 中,并被视为几乎没有对象。如果你做这样的事情,当你取回任何物体时,你无法分辨它是狗还是汽车。这就是警告存在的原因。

      通过使用泛型类型参数(例如 Dog),addAll 定义如下:

       public boolean addAll(java.util.Collection<? extends Dog> es)
      

      这确保参数只能接受 Dog 和 Dog 的子类的集合。因此,当您从集合中检索它时,将检索对象分配给 Dog 是安全的。

      警告不是因为你做错了什么。这是因为 JSONArray 继承了一个非参数化的集合。随意压制它。

      【讨论】:

        【解决方案4】:

        从JSONArray 的文档来看,extends ArrayList 看起来像是原始类型(它没有泛型类型参数)。这是处理非通用遗留代码的示例,唯一的方法是确保JSONArray 预计会收到一些Strings,然后取消警告。

        (修复它的真正方法是更新JSONArray 以使用泛型,但与此同时,您必须使用原始类型。)

        【讨论】:

          【解决方案5】:

          使用Gson 库将ArrayList 转换为JsonArray。

          Gson gson = new GsonBuilder().create();
          JsonArray myCustomArray = gson.toJsonTree(myCustomList).getAsJsonArray();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-16
            • 2015-01-28
            • 2022-01-15
            • 1970-01-01
            • 2015-09-27
            • 1970-01-01
            • 2016-03-01
            相关资源
            最近更新 更多