【问题标题】:JSON and Generics in Java - Type safety warningJava 中的 JSON 和泛型 - 类型安全警告
【发布时间】:2013-05-01 04:38:51
【问题描述】:

我有一些数据存储在 Java 元素中,我需要以给定的格式返回它 - JSONObject。虽然我的实现工作正常,但我仍然收到来自 eclipse 的警告消息(版本:Juno Service Release 2):

"类型安全:方法 put(Object, Object) 属于原始类型 HashMap。对泛型类型 HashMap 的引用应参数化"

这是我的代码:

public interface Element {...}

public abstract class AbstractElement implements Element {...}

public final class Way extends AbstractElement {...}

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class WayToJsonConverter{
    ...
    public JSONObject wayToJson(){
        JSONObject obj = new JSONObject();
        obj.put("id",way.getId());
        ...
        return obj;
    }
    ...
}

有问题的行是:obj.put("id",way.getId());

除了添加@SuppressWarnings("unchecked")之外,有没有办法解决这个问题?

【问题讨论】:

  • getId()的返回类型是什么?
  • 返回类型为:字符串
  • 这样的话obj.put("id",way.getId());就没有问题了。它必须是其他一些发出警告的行!
  • 如果您将 import 部分添加到代码 sn-p 中会很有帮助。

标签: java json eclipse generics


【解决方案1】:

你的 JSONObject 是什么,它是从 HashMap 继承的吗?如果是这样,警告可能意味着您应该如下声明 JSONObject 实例:

JSONObject<String,Object> obj=new JSONObject<String,Object>();

更新:查看JSONObject的定义:

public class JSONObject extends HashMap

它扩展了HashMap但不支持参数类型,如果它的定义是

public class JSONObject<K,V> extends HashMap<K,V>

那么我们可以写

JSONObject<String,Object> obj=new JSONObject<String,Object>();

并且put方法将不再产生警告

【讨论】:

  • 当我尝试这样做时,我收到消息:“JSONObject 类型不是通用的;它不能用参数 进行参数化”
  • 我发现它扩展了HashMap,但在类定义中没有类型参数,所以我们只能在这里添加@SuppressWarnings("unchecked")...
  • 您可以将最后评论的内容添加到您的答案中吗?您是第一个解释为什么无法解决此问题的人,我想接受您的回答。
  • 看JSONObject的定义:“public class JSONObject extends HashMap”,它扩展了HashMap但不支持参数类型,如果定义是“public class JSONObject extends HashMap” ",那么我们可以写成"JSONObject obj=new JSONObject();",put方法就不会再产生警告了
  • 我正在使用相同的import org.json.simple.JSONObject; 最新版本似乎是1.1.1。是否有可以参数化的更新版本?这是我拥有的:mvnrepository.com/artifact/com.googlecode.json-simple/…
【解决方案2】:

如果您无法切换到另一个库或修改该库的代码以使其成为通用,则唯一的其他选择是围绕该库编写一个使用它的包装器,并正确支持泛型。

因此,您将拥有自己的 JSONObject 类,该类将包含 org.json.simple.JSONObject,扩展 HashMap&lt;String, Object&gt; 并实现 Map&lt;String, Object&gt;,并将包含 org.json.simple.JSONObject 的所有方法的转发方法。

您仍然必须将@SuppressWarnings("unchecked") 放在此类中,但仅限于此类,并且您的所有其余代码都可以没有一般​​警告或抑制它们。

【讨论】:

  • 如果我仍然需要使用 suppressWarning 我没有解决问题,而是将其移动了。就目前而言,所有 JSON 处理都在一个类中完成,因此对我没有多大帮助。此外,我需要将一个 JSONObject 返回给我正在实现的接口的某些方法,所以无论如何 Warping 它对我没有帮助。看来这是给定 JSON 包的一个限制,我不能做太多让它看起来更好。
【解决方案3】:

公共类 JSONObject 扩展 HashMap 实现 Map、JSONAware、JSONStreamAware

但在类定义中没有类型参数,您唯一的选择是添加@SuppressWarnings("unchecked")

【讨论】:

    【解决方案4】:

    您可以创建一个地图对象,然后显式转换为 JSONObject

    Map<String, String> obj =  new HashMap<String, String>();
    obj.put("id",way.getId());
    JSONObject jsonObj =  (JSONObject) obj;
    

    但请注意,这将限制您在 JSON 中仅包含“字符串”。如果您放置另一个数据结构,您将看到编译错误。说一个数组。

    【讨论】:

    • 以上情况无需添加“抑制警告”注解
    • java.util.HashMap cannot be cast to org.json.simple.JSONObject
    【解决方案5】:

    仅供参考org.codehaus.jettison.json.JSONObject 不会导致此警告。使用 codehaus 的 JSONObject 时,您还可以通过 org.codehaus.jettison.json.JSONException 捕获解析错误。详情请见https://github.com/codehaus/jettison

    【讨论】:

      【解决方案6】:

      另一个选项是使用(参数化的)Map&lt;String, Object&gt; 初始化JSONObject。这样,值可以是任何有效的 JSON 类型,并且您可以避免 unchecked 警告。例如:

      public class WayToJsonConverter{
          ...
          public JSONObject wayToJson(){
              Map<String, Object> forJsonObj = new HashMap<>();
              forJsonObj.put("id",way.getId());  // No warning, hurray!
              forJsonObj.put("integer", 14);
              forJsonObj.put("floating", 1.4);
              JSONObject obj = new JSONObject(forJsonObj);
              ...
              return obj;
          }
          ...
      }
      

      【讨论】:

      • JSONObject 没有参数化构造函数。
      • @HarshPandey- 我的回答中没有使用 JSONObject 的参数化构造函数。
      • JSONObject obj = new JSONObject(forJsonObj);这里没有使用参数化构造函数吗?
      • 哦,你的意思是构造函数在构造函数中接收到Map参数?我误解了你的评论。无论如何,我使用this 作为参考。
      • 您的参考指向org.json.JSONObject,而OP 使用的是org.json.simple.JSONObject
      【解决方案7】:

      尝试将 put 行改为 other

       JsonPath.parse(jsonObj).set(fieldPath, Value);
      

      【讨论】:

        猜你喜欢
        • 2021-03-27
        • 1970-01-01
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2013-05-17
        • 2012-04-07
        • 2012-04-20
        相关资源
        最近更新 更多