13
votes

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")?

7
what is the return type of getId()?RainMaker
The return type is : StringItay Gal
In that case, there is no problem with obj.put("id",way.getId());. It has to be some other line which gives that warning!RainMaker
Would be helpful if you added your import section to the code snippet.Adam Adamaszek

7 Answers

15
votes

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

2
votes

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.

1
votes

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")

0
votes

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.

0
votes

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.

0
votes

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. E.g.:

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

try to change the put line to other

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