Как я обращаюсь к непроверенным предупреждениям броска? - PullRequest
551 голосов
/ 04 февраля 2009

Затмение дает мне предупреждение следующего вида:

Тип безопасности: непроверенное приведение из объекта в HashMap

Это вызов API, который я не могу контролировать, который возвращает Object:

HashMap<String, String> getItems(javax.servlet.http.HttpSession session) {
  HashMap<String, String> theHash = (HashMap<String, String>)session.getAttribute("attributeKey");
  return theHash;
}

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

До того, как я пришел к коду, он был проще, но все равно вызывал предупреждения:

HashMap getItems(javax.servlet.http.HttpSession session) {
  HashMap theHash = (HashMap)session.getAttribute("attributeKey");
  return theHash;
}

Проблема была в другом месте, когда вы пытались использовать хеш, вы получите предупреждения:

HashMap items = getItems(session);
items.put("this", "that");

Type safety: The method put(Object, Object) belongs to the raw type HashMap.  References to generic type HashMap<K,V> should be parameterized.

Ответы [ 24 ]

0 голосов
/ 04 февраля 2009

Проблема заключается здесь:

... = (HashMap<String, String>)session.getAttribute("attributeKey");

Результат session.getAttribute(...) - это object, который может быть чем угодно, но, поскольку вы "знаете", что это HashMap<String, String>, вы просто разыгрываете, не проверяя его первым. Итак, предупреждение. Чтобы быть педантичным, каким Java хочет, чтобы вы были в этом случае, вы должны получить результат и проверить его совместимость с instanceof.

0 голосов
/ 01 марта 2013

Решение: отключите это предупреждение в Eclipse. Не @SuppressWarnings, просто полностью отключите его.

Некоторые из «решений», представленных выше, выходят за рамки обычного, делая код нечитаемым для подавления глупого предупреждения.

0 голосов
/ 24 августа 2010

Это заставляет предупреждения уходить ...

 static Map<String, String> getItems(HttpSession session) {
        HashMap<?, ?> theHash1 = (HashMap<String,String>)session.getAttribute("attributeKey");
        HashMap<String,String> theHash = (HashMap<String,String>)theHash1;
    return theHash;
}
0 голосов
/ 21 марта 2011

Два способа, один из которых полностью избегает тег, другой использует непослушный, но приятный служебный метод.
Проблема в предварительно обобщенных коллекциях ...
Я полагаю, что эмпирическое правило гласит: «бросать объекты по одной за раз» - что это означает, когда вы пытаетесь использовать необработанные классы в обобщенном мире, потому что вы не знаете, что находится на этой карте <?,?> ( и действительно, JVM может даже обнаружить, что это даже не Карта!), когда вы думаете об этом, вы не можете разыграть ее. Если у вас есть Map Map2, то HashSet keys = (HashSet ) map2.keySet () не выдает предупреждение, несмотря на то, что это «акт веры» для компилятора (потому что это может оказаться TreeSet) ... но это всего лишь один акт веры.

PS на возражение, что повторение, как в моем первом случае, «скучно» и «требует времени», ответ «нет боли, нет выгоды»: обобщенная коллекция гарантированно содержит Map.Entry s и ничего остальное. Вы должны заплатить за эту гарантию. При систематическом использовании непатентованных средств этот платеж, естественно, принимает форму соответствия кодирования, а не машинного времени!
Одна школа мысли может сказать, что вы должны установить настройки Eclipse, чтобы делать такие неконтролируемые ошибки, а не предупреждения. В этом случае вам придется использовать мой первый способ.

package scratchpad;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

public class YellowMouse {

    // First way

    Map<String, String> getHashMapStudiouslyAvoidingSuppressTag(HttpSession session) {
      Map<?, ?> theHash = (Map<?, ?>)session.getAttribute("attributeKey");

      Map<String, String> yellowMouse = new HashMap<String, String>();
      for( Map.Entry<?, ?> entry : theHash.entrySet() ){
        yellowMouse.put( (String)entry.getKey(), (String)entry.getValue() );
      }

      return yellowMouse;
    }


    // Second way

    Map<String, String> getHashMapUsingNaughtyButNiceUtilityMethod(HttpSession session) {
      return uncheckedCast( session.getAttribute("attributeKey") );
    }


    // NB this is a utility method which should be kept in your utility library. If you do that it will
    // be the *only* time in your entire life that you will have to use this particular tag!!

    @SuppressWarnings({ "unchecked" })
    public static synchronized <T> T uncheckedCast(Object obj) {
        return (T) obj;
    }


}
...