Как решить эту безопасность типов Java, предупреждающую?

Map session = ActionContext.getContext().getSession();
session.put("user", user);

Этот код генерирует предупреждение: Безопасность с точки зрения типов: помещенный метод (Объект, Объект) принадлежит необработанной Карте типа. Ссылки на универсальную Карту типа <K, V> должны быть параметризованы.

Map<String, Serializable> session = (Map<String, Serializable>)ActionContext.getContext().getSession();
session.put("user", user);

Этот код генерирует предупреждение: Безопасность с точки зрения типов: Неконтролируемый бросок от Карты до Карты <Строка, сериализуемая>.

getSession метод принадлежит Struts2, таким образом, я не могу изменить его. Я хотел бы избегать использования @SuppressWarnings, потому что другие предупреждения могут быть полезными.

Я предполагаю, что все пользователи Struts2 в мире столкнулись с той же проблемой... там изящное решение?

12
задан sjngm 29 June 2015 в 06:55
поделиться

4 ответа

Я не думаю, что есть другой способ, кроме @SuppressWarnings("unchecked"). Я полагаю, вы можете поместить его прямо над рассматриваемой строкой, и он будет подавлять только эту строку.

Edit: вы также можете сделать Map session = ActionContext.getContext().getSession(); но я не уверен, насколько вы готовы это сделать; вы не сможете ничего поместить в карту таким образом (поскольку компилятор не может проверить тип того, что вы помещаете), только читать из нее.

11
ответ дан 2 December 2019 в 19:30
поделиться

Какую версию Struts 2 (особенно XWork ) вы используете? Для меня ваш следующий код дает ошибку:

Map<String, Serializable> session = (Map<String, Serializable>)ActionContext.getContext().getSession();
session.put("user", user);

Cannot cast from Map<String,Object> to Map<String,Serializable>.

Это, с другой стороны, работает и не дает предупреждений:

Map<String, Object> session = ActionContext.getContext().getSession();
1
ответ дан 2 December 2019 в 19:30
поделиться

Самый безопасный и эффективный способ решения этой проблемы, вероятно, следующий:

Map<?, ?> session = ActionContext.getContext().getSession();

и затем приведение типов объектов, полученных из карты сессии.

Подход @SuppressWarnings фактически приведет к идентичному скомпилированному коду. Однако приведение типов будет неявным, т.е. его будет нелегко обнаружить, взглянув на исходный код. А аннотация @SuppressWarnings может (гипотетически) подавить какое-то другое предупреждение в том же блоке кода, которое представляет собой реальную ошибку; т.е. такую, которая приведет к тому, что один из скрытых типов и т.д. не сработает во время выполнения.

Другие более дорогие альтернативы включают в себя:

  • копирование элемента за элементом из Map в новый экземпляр Map с приведением ключей и значений к String и Serializable соответственно, или

  • общий метод, подобный следующему, который безопасно выполняет типизацию.


@SuppressWarnings("unchecked")
public <K,V> Map<K,V> castMap(Map<?, ?> map, Class<K> kClass, Class<V> vClass) {
    for (Map.Entry<?, ?> entry : map.entrySet()) {
        kClass.cast(entry.getKey());
        vClass.cast(entry.getValue());
    }
    return (Map<K,V>) map;
}
5
ответ дан 2 December 2019 в 19:30
поделиться

Что, если вы сделаете это вот так :

Map<String, Serializable> session = ActionContext.getContext().getSession();
0
ответ дан 2 December 2019 в 19:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: