如何解决未经检查的投射警告?

2022-08-31 04:09:58

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

类型安全:未经检查的从对象到哈希映射的转换

这是从对API的调用,我无法控制哪个返回Object:

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

如果可能的话,我想避免使用 Eclipse 警告,因为从理论上讲,它们至少表明了潜在的代码问题。不过,我还没有找到一个好方法来消除这个。我可以将所涉及的单行提取到方法本身并添加到该方法中,从而限制了具有忽略警告的代码块的影响。还有更好的选择吗?我不想在 Eclipse 中关闭这些警告。@SuppressWarnings("unchecked")

在我编写代码之前,它更简单,但仍然引发了警告:

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.

答案 1

当然,显而易见的答案是不要进行未经检查的演员。

如果绝对必要,那么至少尝试限制注释的范围。根据其Javadocs,它可以使用局部变量;这样,它甚至不会影响整个方法。@SuppressWarnings

例:

@SuppressWarnings("unchecked")
Map<String, String> myMap = (Map<String, String>) deserializeMap();

没有办法确定是否真的应该有泛型参数。您必须事先知道参数应该是什么(或者当您获得时会发现)。这就是代码生成警告的原因,因为编译器不可能知道是否安全。Map<String, String>ClassCastException


答案 2

不幸的是,这里没有好的选择。请记住,所有这一切的目标都是为了保持类型安全。“Java Generics”提供了一个处理非泛型化遗留库的解决方案,在第8.2节中有一个特别称为“空循环技术”的解决方案。基本上,使不安全的演员,并抑制警告。然后像这样循环浏览地图:

@SuppressWarnings("unchecked")
Map<String, Number> map = getMap();
for (String s : map.keySet());
for (Number n : map.values());

如果遇到意外的类型,您将获得一个 运行时 ,但至少它将发生在接近问题根源的地方。ClassCastException


推荐