当前位置: 首页 > 面试题库 >

Java如何解决未经检查的演员表警告?

乌修筠
2023-03-14
问题内容

Eclipse给我以下形式的警告:

类型安全性:未经检查的从Object到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.

问题答案:

问题是没有检查演员表。因此,你必须自己检查。你不能只使用instanceof检查参数化类型,因为参数化类型信息在运行时不可用,在编译时已被擦除。

但是,你可以使用instanceof对散列中的每个项目执行检查,并以此来构造类型安全的新散列。而且你不会招来任何警告。

感谢mmyers和Esko Luontola,我已经将我最初在此处编写的代码参数化了,因此可以将其包装在某个实用程序类中的某个地方,并用于任何参数化的HashMap。如果你想更好地理解它并且对泛型不是很熟悉,建议你查看此答案的编辑历史记录。

public static <K, V> HashMap<K, V> castHash(HashMap input,
                                            Class<K> keyClass,
                                            Class<V> valueClass) {
  HashMap<K, V> output = new HashMap<K, V>();
  if (input == null)
      return output;
  for (Object key: input.keySet().toArray()) {
    if ((key == null) || (keyClass.isAssignableFrom(key.getClass()))) {
        Object value = input.get(key);
        if ((value == null) || (valueClass.isAssignableFrom(value.getClass()))) {
            K k = keyClass.cast(key);
            V v = valueClass.cast(value);
            output.put(k, v);
        } else {
            throw new AssertionError(
                "Cannot cast to HashMap<"+ keyClass.getSimpleName()
                +", "+ valueClass.getSimpleName() +">"
                +", value "+ value +" is not a "+ valueClass.getSimpleName()
            );
        }
    } else {
        throw new AssertionError(
            "Cannot cast to HashMap<"+ keyClass.getSimpleName()
            +", "+ valueClass.getSimpleName() +">"
            +", key "+ key +" is not a " + keyClass.getSimpleName()
        );
    }
  }
  return output;
}

这项工作量很大,可能只获得很少的报酬…我不确定是否会使用它。对于人们认为是否值得的任何评论,我将不胜感激。另外,我也很高兴提出改进建议:除了抛出AssertionErrors之外,我还能做点更好的事情吗?有什么我可以扔的更好的东西吗?我应该将其设为检查异常吗?



 类似资料:
  • 问题内容: 我认为我得到了未经检查的演员表的含义(从一个类型转换到另一种类型),但是“检查”演员表意味着什么?如何检查演员表,以便可以避免在Eclipse中出现此警告? 问题答案: 未检查的强制转换意味着(隐式或显式)您正在从泛型类型转换为非限定类型,或者反之。例如这条线 会产生这样的警告。 通常有这样的警告是有充分的理由的,因此您应该尝试改进代码而不是禁止警告。引用来自有效Java,第二版: 消

  • 问题内容: 在我的spring应用程序上下文文件中,我有类似以下内容: 在java类中,实现如下所示: 在Eclipse中,我看到一条警告: 类型安全性:未经检查的从Object到HashMap的转换 我做错什么了?我该如何解决该问题? 问题答案: 好吧,首先,你正在通过新的HashMap创建调用浪费内存。你的第二行完全忽略了对此创建的哈希图的引用,从而使该哈希图可用于垃圾收集器。因此,不要这样做

  • 问题内容: 不知何故,我的旧问题已关闭,因此我打开了一个新问题: 我正在使用Java泛型从SQL查询中实现泛型双向Hash Map。它应该能够来回映射String,Integer对的任何组合。应该这样使用: 当然应该可以创建一个pm(Integer,Integer)等等。 我选择地图的实现如下所示(没有getter …): 我没有编译器错误,而且我很确定,它将以这种方式工作。但是我在“ getIn

  • 问题内容: 我正在尝试制作一个称为myHash的Point HashSet的浅表副本。截至目前,我有以下内容: 这段代码给了我一个未经检查的强制转换警告。有一个更好的方法吗? 问题答案: 您可以尝试以下方法:

  • 问题内容: 我有一个不是actor的java对象,它使用actorSelection(Path)从一个actor系统中选择actor。系统中可能不存在所选参与者。 在Java Api中,ActorSelection不存在ask(),因此我无法向actor选择发送和标识消息并使用响应的发送者。 我试图通过演员选择将消息发送给演员,然后对死信做出反应来解决该问题。但是我没有任何死信。 如何通过Acto

  • 我收到循环条件检查问题的未检查输入 我尝试了推荐的代码处理,但它对我不起作用。 检查马克思报告的描述: 我尝试了下面的代码: