简体   繁体   中英

JSON and Generics in Java - Type safety warning

I have some data stored in Java elements and I need to return it in a given format - JSONObject. While my implementation works fine, I'm still getting a warning message from eclipse (Version: Juno Service Release 2):

" Type safety: The method put(Object, Object) belongs to the raw type HashMap. References to generic type HashMap should be parameterized "

This is my code:

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;
    }
    ...
}

The problematic line is : obj.put("id",way.getId());

Is there a way to solve this issue other then adding @SuppressWarnings("unchecked") ?

What is your JSONObject, does it inherit from HashMap? If does, the warn probably means that your should declare the JSONObject instance as follows:

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

Updated: Look at the definition of the JSONObject:

public class JSONObject extends HashMap

it extends HashMap but doesn't support parameter type, if its definition is

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

then we could write

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

and the put method will no longer generate the warning

If you can't switch to another library or modify the code of this library to make it generic, the only other option would be to write a wrapper around this library which uses it, and properly supports generics.

So you would have your own JSONObject class which would contain an org.json.simple.JSONObject , would extend HashMap<String, Object> and implement Map<String, Object> , and would contain forwarding methods for all the methods of org.json.simple.JSONObject .

You would still have to put @SuppressWarnings("unchecked") in this class, but it would be limited to this class, and all the rest of your code could be free of generic warnings or the suppression of them.

public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware

But does not have type parameter in class definition, The only option you have is to add the @SuppressWarnings("unchecked")

FYI org.codehaus.jettison.json.JSONObject will not cause this warning. When using codehaus' JSONObject, you also have the ability to catch parsing errors via org.codehaus.jettison.json.JSONException . See https://github.com/codehaus/jettison for details.

You could create a map object and then do an explicit cast to JSONObject

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

But note that this will restrict you only include "Strings" in your JSON. and you will see compile errors if you put another data structure. Say an array.

Another option is to initialize the JSONObject with a (parameterized) Map<String, Object> . That way, a value can be of any valid JSON type, and you avoid the unchecked warning. Eg:

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;
    }
    ...
}

尝试将放置线更改为其他

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM