Eclipse给我一个如下形式的警告:

类型安全:未检查从对象转换到HashMap

这是从一个API调用,我无法控制返回对象:

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.

当前回答

您可以创建如下所示的实用程序类,并使用它来抑制未检查的警告。

public class Objects {

    /**
     * Helps to avoid using {@code @SuppressWarnings({"unchecked"})} when casting to a generic type.
     */
    @SuppressWarnings({"unchecked"})
    public static <T> T uncheckedCast(Object obj) {
        return (T) obj;
    }
}

你可以这样使用它:

import static Objects.uncheckedCast;
...

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

这里有更多关于这个问题的讨论: http://cleveralias.blogs.com/thought_spearmints/2006/01/suppresswarning.html

其他回答

快速猜测一下你是否发布了你的代码,可以肯定地说,但是你可能做了一些类似的事情

HashMap<String, Object> test = new HashMap();

当你需要做的时候,哪个会产生警告

HashMap<String, Object> test = new HashMap<String, Object>();

也许值得一看

Java编程语言中的泛型

如果你不熟悉需要做什么。

我可能误解了这个问题(一个示例和几行代码就好了),但是为什么您不总是使用合适的接口(和Java5+)呢?我看不出为什么你想要强制转换到HashMap而不是Map<KeyType,ValueType>。事实上,我想不出有什么理由将变量的类型设置为HashMap而不是Map。

为什么源是一个对象?是遗留集合的参数类型吗?如果是,请使用泛型并指定所需的类型。

如果我不得不使用一个不支持泛型的API ..我尝试用尽可能少的行将这些调用隔离在包装器例程中。然后我使用SuppressWarnings注释并同时添加类型安全类型强制转换。

这只是个人的喜好,想让事情尽可能的整洁。

在Eclipse首选项中,转到Java->编译器->错误/警告->泛型类型,并选中“忽略不可避免的泛型类型问题”复选框。

这满足了问题的意图,即。

我希望避免Eclipse警告……

如果不是精神。

的对象。Esko Luontola上面回答的未检查的实用函数是避免程序混乱的好方法。

如果您不希望在整个方法上使用SuppressWarnings, Java会强制您将其放在本地方法上。如果你需要对一个成员进行强制转换,可能会导致这样的代码:

@SuppressWarnings("unchecked")
Vector<String> watchedSymbolsClone = (Vector<String>) watchedSymbols.clone();
this.watchedSymbols = watchedSymbolsClone;

使用这个实用程序要干净得多,而且你所做的事情仍然很明显:

this.watchedSymbols = Objects.uncheckedCast(watchedSymbols.clone());

注意: 我觉得有必要补充一下,有时候警告真的意味着你做错了什么,比如:

ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1);
Object intListObject = intList; 

 // this line gives an unchecked warning - but no runtime error
ArrayList<String> stringList  = (ArrayList<String>) intListObject;
System.out.println(stringList.get(0)); // cast exception will be given here

编译器告诉您的是,在运行时不会检查此强制转换,因此在尝试访问泛型容器中的数据之前不会引发运行时错误。