如何解决未经检查的强制转换警告? [英] How do I address unchecked cast warnings?

查看:31
本文介绍了如何解决未经检查的强制转换警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Eclipse 向我发出以下形式的警告:

Eclipse is giving me a warning of the following form:

类型安全:从 Object 到 HashMap 的未经检查的转换

Type safety: Unchecked cast from Object to HashMap

这是来自对 API 的调用,我无法控制哪个返回对象:

This is from a call to an API that I have no control over which returns 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 中关闭这些警告.

I'd like to avoid Eclipse warnings, if possible, since theoretically they indicate at least a potential code problem. I haven't found a good way to eliminate this one yet, though. I can extract the single line involved out to a method by itself and add @SuppressWarnings("unchecked") to that method, thus limiting the impact of having a block of code where I ignore warnings. Any better options? I don't want to turn these warnings off in Eclipse.

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

Before I came to the code, it was simpler, but still provoked warnings:

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

当您尝试使用散列时,问题出在其他地方,您会收到警告:

Problem was elsewhere when you tried to use the hash you'd get warnings:

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.

推荐答案

Wow;我想我找到了自己问题的答案.我只是不确定它是否值得!:)

Wow; I think I figured out the answer to my own question. I'm just not sure it's worth it! :)

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

The problem is the cast isn't checked. So, you have to check it yourself. You can't just check a parameterized type with instanceof, because the parameterized type information is unavailable at runtime, having been erased at compile time.

但是,您可以使用 instanceof 对散列中的每一项进行检查,这样您就可以构造一个类型安全的新散列.而且你不会引起任何警告.

But, you can perform a check on each and every item in the hash, with instanceof, and in doing so, you can construct a new hash that is type-safe. And you won't provoke any warnings.

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

Thanks to mmyers and Esko Luontola, I've parameterized the code I originally wrote here, so it can be wrapped up in a utility class somewhere and used for any parameterized HashMap. If you want to understand it better and aren't very familiar with generics, I encourage viewing the edit history of this answer.

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 之外,我还能做些什么更好的事情吗?有什么更好的东西我可以扔吗?我应该让它成为一个检查异常吗?

That's a lot of work, possibly for very little reward... I'm not sure if I'll use it or not. I'd appreciate any comments as to whether people think it's worth it or not. Also, I'd appreciate improvement suggestions: is there something better I can do besides throw AssertionErrors? Is there something better I could throw? Should I make it a checked Exception?

这篇关于如何解决未经检查的强制转换警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆