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")之外,还有其他方法来解决这个问题吗?
- getId()的返回类型是什么?
- 返回类型为:string
- 在这种情况下,obj.put("id",way.getId());没有问题。一定是另一条线发出了警告!
- 如果您将您的import部分添加到代码片段中,将会很有帮助。
您的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不是泛型的;它不能用参数参数化。"
- 第三方。你可以在这里找到它:code.google.com/p/json-simple
- 我发现它扩展了hashmap,但在类定义中没有类型参数,所以我们只能在这里添加@suppresswarnings("unchecked")。
- 你能在你的答案中加上最后一条评论的内容吗?你是第一个解释为什么这个问题不能解决的人,我想接受你的回答。
- 看看jsonObject的定义:"public class jsonObject extends hashmap",它扩展hashmap但不支持参数类型,如果它的定义是"public class jsonObjectextends hashmap",那么我们就可以写"jsonObjectobj=new jsonObject();",而put方法将不再生成wa。莱宁
- 我使用的是同一个import org.json.simple.JSONObject;,最新的版本似乎是1.1.1。是否有可以参数化的较新版本?这就是我拥有的:mvnrepository.com/artifact/com.googlecode.json simple/&hellip;
如果无法切换到其他库或修改此库的代码使其成为通用库,则唯一的其他选项是围绕使用它的库编写一个包装器,并正确支持泛型。
因此,您将拥有自己的JSONObject类,它将包含org.json.simple.JSONObject,将扩展HashMap并实现Map,并且将包含org.json.simple.JSONObject的所有方法的转发方法。
您仍然需要将@SuppressWarnings("unchecked")放在这个类中,但是它将被限制在这个类中,并且您的代码的其余部分可能没有一般警告或抑制它们。
- 如果我还需要使用SuppressWarning,我没有解决问题,而是移动了它。至于现在,所有的JSON处理都是在一个类中完成的,所以这对我没有太大帮助。此外,我需要将JSONObject返回到我正在实现的接口的某些方法中,因此对它进行变形无论如何都不会对我有所帮助。这似乎是给定JSON包的一个限制,我不能做太多的工作来让它看起来更好。
公共类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没有参数化构造函数。
- @Harshpandey-我的答案中没有使用JSONObject的参数化构造函数。
- JSONObject obj = new JSONObject(forJsonObj);这里是否不使用参数化构造函数?
- 哦,你的意思是构造函数在构造函数中接收一个Map参数?我误解了你的评论。不管怎样,我用这个作为参考。
- 您的参考指向org.json.JSONObject,而op使用org.json.simple.JSONObject。
- org.json.simple.JSONObject还有一个参数化的构造函数,它接受Map:juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/&hellip;
- 我现在明白了困惑。JSONObject的这个实现确实有一个参数化的构造函数。我使用的实现没有参数化构造函数。
- 实际上,您引用的实现没有参数化的构造函数。
- 哈哈,对不起,我一定是找错了。我当前在生产中使用的没有参数化构造函数。但是我要换一个有它的。
您可以创建一个映射对象,然后显式转换为JSONObject。
1 2 3
| 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
Fyi org.codehaus.jettison.json.JSONObject不会引起此警告。使用codehaus的jsonObject时,还可以通过org.codehaus.jettison.json.JSONException捕获解析错误。有关详细信息,请参阅https://github.com/codehaus/jettison。