JSON и Generics в Java - Введите предупреждение о безопасности
У меня есть некоторые данные, хранящиеся в элементах 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")
?
Ответы
Ответ 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 больше не будет генерировать предупреждение
Ответ 2
Если вы не можете переключиться на другую библиотеку или изменить код этой библиотеки, чтобы сделать ее общей, единственной другой возможностью было бы написать обертку вокруг этой библиотеки, которая ее использует, и правильно поддерживает генерики.
Таким образом, у вас будет свой собственный класс JSONObject
, который будет содержать org.json.simple.JSONObject
, расширяет HashMap<String, Object>
и реализует Map<String, Object>
и будет содержать методы пересылки для всех методов org.json.simple.JSONObject
.
Вам все равно придется помещать @SuppressWarnings("unchecked")
в этот класс, но он будет ограничен этим классом, и весь остальной код может быть свободен от общих предупреждений или подавления их.
Ответ 3
FYI org.codehaus.jettison.json.JSONObject
не будет вызывать это предупреждение. При использовании JSONObject от Codehaus у вас также есть возможность поймать ошибки анализа с помощью org.codehaus.jettison.json.JSONException
. Подробнее см. https://github.com/codehaus/jettison.
Ответ 4
Вы можете создать объект карты, а затем выполнить явное преобразование в JSONObject
Map<String, String> obj = new HashMap<String, String>();
obj.put("id",way.getId());
JSONObject jsonObj = (JSONObject) obj;
Но обратите внимание, что это ограничит вас только включением "Строки" в вашем JSON. и вы увидите ошибки компиляции, если вы поместите другую структуру данных. Скажем массив.
Ответ 5
Другой вариант - инициализировать JSONObject
с помощью (параметризованного) Map<String, Object>
. Таким образом, значение может быть любого допустимого типа 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;
}
...
}