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 в мире столкнулись с той же проблемой... там изящное решение?
Я не думаю, что есть другой способ, кроме @SuppressWarnings("unchecked"). Я полагаю, вы можете поместить его прямо над рассматриваемой строкой, и он будет подавлять только эту строку.
Edit: вы также можете сделать Map, ?> session = ActionContext.getContext().getSession();
но я не уверен, насколько вы готовы это сделать; вы не сможете ничего поместить в карту таким образом (поскольку компилятор не может проверить тип того, что вы помещаете), только читать из нее.
Какую версию 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();
Самый безопасный и эффективный способ решения этой проблемы, вероятно, следующий:
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;
}
Что, если вы сделаете это вот так :
Map<String, Serializable> session = ActionContext.getContext().getSession();