关于Java中的JSON和泛型:Java中的JSON和泛型 – 类型安全警告

JSON and Generics in Java - Type safety warning

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

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

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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")之外,还有其他方法来解决这个问题吗?


您的jsonObject是什么,它继承自hashmap吗?如果是这样,警告可能意味着您应该按如下方式声明JSONObject实例:

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

更新:查看jsonObject的定义:

1
public class JSONObject extends HashMap

它扩展了hashmap,但不支持参数类型(如果其定义为

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

然后我们可以写

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

Put方法将不再生成警告


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

因此,您将拥有自己的JSONObject类,它将包含org.json.simple.JSONObject,将扩展HashMap并实现Map,并且将包含org.json.simple.JSONObject的所有方法的转发方法。

您仍然需要将@SuppressWarnings("unchecked")放在这个类中,但是它将被限制在这个类中,并且您的代码的其余部分可能没有一般警告或抑制它们。


公共类jsonObject扩展hashmap实现map、jsonaware、jsonstreamaware

但在类定义中没有类型参数,只能添加@suppresswarnings("unchecked")。


另一种选择是用(参数化的)Map初始化JSONObject。这样,一个值可以是任何有效的JSON类型,并且可以避免unchecked警告。例如。:

1
2
3
4
5
6
7
8
9
10
11
12
13
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。

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

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


Fyi org.codehaus.jettison.json.JSONObject不会引起此警告。使用codehaus的jsonObject时,还可以通过org.codehaus.jettison.json.JSONException捕获解析错误。有关详细信息,请参阅https://github.com/codehaus/jettison。