В моем весеннем контексте приложения у меня есть что-то вроде:
<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String">
<entry key="some_key" value="some value" />
<entry key="some_key_2" value="some value" />
</util:map>
В классе Java реализация выглядит так:
private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
В Eclipse я вижу предупреждение, которое гласит:
Безопасность типов: непроверенное приведение от объекта к HashMap
Что я сделал не так? Как мне решить проблему?
java
spring
type-safety
unchecked
драконорожденные
источник
источник
Ответы:
Ну, во-первых, вы тратите память на новый
HashMap
вызов создания. Ваша вторая строка полностью игнорирует ссылку на этот созданный hashmap, делая его доступным для сборщика мусора. Итак, не делайте этого, используйте:Во-вторых, компилятор жалуется, что вы приводите объект к
HashMap
без проверки, является ли онHashMap
. Но, даже если вы должны были сделать:Вы, вероятно, все еще получите это предупреждение. Проблема в том, что
getBean
возвращаетсяObject
, поэтому неизвестно, что это за тип. Преобразование вHashMap
напрямую не вызовет проблемы во втором случае (и, возможно, в первом случае не будет предупреждения, я не уверен, насколько педантичен компилятор Java с предупреждениями для Java 5). Тем не менее, вы конвертируете его вHashMap<String, String>
.HashMaps - это действительно карты, которые принимают объект в качестве ключа и имеют объект в качестве значения,
HashMap<Object, Object>
если хотите. Таким образом, нет никакой гарантии, что когда вы получите свой bean-компонент, он может быть представлен как,HashMap<String, String>
потому что вы можете иметь это,HashMap<Date, Calendar>
потому что возвращаемое неуниверсальное представление может иметь любые объекты.Если код компилируется, и вы можете выполнить его
String value = map.get("thisString");
без ошибок, не беспокойтесь об этом предупреждении. Но если карта не полностью содержит строковые ключи для строковых значений, вы получитеClassCastException
во время выполнения, потому что в этом случае универсальные блоки не могут этого предотвратить.источник
Проблема в том, что приведение является проверкой во время выполнения, но из-за стирания типа во время выполнения на самом деле нет разницы между a
HashMap<String,String>
иHashMap<Foo,Bar>
любым другимFoo
иBar
.Используйте
@SuppressWarnings("unchecked")
и держите нос. Ох, и кампания за усовершенствованные дженерики на Java :)источник
Как показывают вышеприведенные сообщения, список нельзя различить между a
List<Object>
и aList<String>
илиList<Integer>
.Я решил это сообщение об ошибке для аналогичной проблемы:
со следующим:
Объяснение: Первое преобразование типов проверяет, что объект является списком, не заботясь о типах, содержащихся в нем (поскольку мы не можем проверить внутренние типы на уровне списка). Второе преобразование теперь требуется, потому что компилятор знает только, что List содержит какие-то объекты. Это проверяет тип каждого объекта в списке по мере его доступа.
источник
Предупреждение только это. Предупреждение. Иногда предупреждения не имеют значения, иногда нет. Они привыкли обращать ваше внимание на то, что компилятор считает проблемой, но может и не быть.
В случае приведения это всегда дает предупреждение в этом случае. Если вы абсолютно уверены, что конкретное приведение будет безопасным, то вам следует рассмотреть возможность добавления аннотации, подобной этой (я не уверен в синтаксисе) непосредственно перед строкой
источник
Вы получаете это сообщение, потому что getBean возвращает ссылку на объект, и вы приводите его к правильному типу. Java 1.5 дает вам предупреждение. Такова природа использования Java 1.5 или выше с кодом, который работает следующим образом. Spring имеет типобезопасную версию
в его списке задач.
источник
Если вы действительно хотите избавиться от предупреждений, вы можете сделать одну вещь - создать класс, который выходит за пределы общего класса.
Например, если вы пытаетесь использовать
Вы можете создать новый класс, как такой
Затем, когда вы используете
Компилятор знает, что это за типы (больше не являются общими), и предупреждений не будет. Это не всегда может быть идеальным решением, некоторые могут возразить, что такого рода поражает назначение универсальных классов, но вы все еще повторно используете все тот же код из универсального класса, вы просто объявляете во время компиляции, какой тип Вы хотите использовать.
источник
Решение, чтобы избежать непроверенного предупреждения:
источник
Другим решением, если вы часто используете один и тот же объект и не хотите засорять свой код
@SupressWarnings("unchecked")
, было бы создание метода с аннотацией. Таким образом, вы централизуете приведение и, надеюсь, уменьшаете вероятность ошибки.источник
Ниже приведен код причины Тип безопасности Предупреждение
Map<String, Object> myInput = (Map<String, Object>) myRequest.get();
Создайте новый объект карты без упоминания параметров, поскольку тип объекта, который содержится в списке, не проверен.
Шаг 1: Создайте новую временную карту
Map<?, ?> tempMap = (Map<?, ?>) myRequest.get();
Шаг 2: Создание основной карты
Шаг 3: Итерация временной карты и установка значений в основную карту
источник
Вот :
Map<String,String> someMap = (Map<String,String>)getApplicationContext().getBean("someMap");
Вы используете устаревший метод, который мы обычно не хотим использовать, так как он возвращает
Object
:Метод для получения (для синглтона) / создания (для прототипа) компонента из фабрики компонентов:
Используя это как:
будет компилироваться, но все еще с предупреждением о непроверенном преобразовании, так как все
Map
объекты не обязательноMap<String, String>
объектами.Но
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
этого недостаточно в универсальных классах bean-компонентов, таких как универсальные коллекции, поскольку для этого требуется указать более одного класса в качестве параметра: тип коллекции и ее универсальный тип (типы).В этом сценарии и в целом, лучший подход не использовать напрямую
BeanFactory
методов, а возможность структуры для внедрения компонента.Объявление бина:
Инъекция бобов:
источник