【问题标题】:Unchecked cast in Java when casting to list of superclasses转换为超类列表时在 Java 中未经检查的转换
【发布时间】:2011-05-27 16:25:50
【问题描述】:

在我的 Java 程序中,我需要将 List<? extends SomeBaseClass> 类型的对象强制转换为 List<SomeBaseClass>。如果我直接转换它,编译器会抱怨(显示警告)存在未经检查的转换。即使我可以确定所有对象都可以转换为它们的超类,编译器不会注意到它并报告未经检查的强制转换。我怎样才能摆脱警告?除了@SupressWarnings("unchecked") 还有其他方法吗?

P.S.:代码运行良好,我只是好奇是否有更好的处理方式。

编辑:

解决方案:如果他确定将来不会更改列表,则应该只进行这种类型的演员表。但是,当我们将单个对象从列表中取出时,最好对它们进行强制转换。

【问题讨论】:

  • 作为一般规则,您可以通过不返回通配符类型来减少这些转换的需要。在将通配符类型作为参数的方法中,您应该有很少的地方必须重复通配符(如迭代器变量),并且我确实会重复通配符,所以我不会意外添加到列表中一个未知的亚型。

标签: java casting suppress-warnings unchecked


【解决方案1】:

编译器抱怨说,如果您将 SomeBaseClass 类型的对象添加到您的 List<SomeBaseClass> 列表中,您可能会“违反”您的 List<? extends SomeBaseClass> 列表的内容。

这里以Number 表示您的SomeBaseClass 为例:

List<? extends Number> doubles = new ArrayList<Double>();
List<Number> nums = (List<Number>) doubles;

nums.add(new Integer(5));    // no compiler complaints here...

// doubles now contains an Integer value!

如果您无法解决此问题,我相信@SuppressWarnings("unchecked") 是您最好的选择。

【讨论】:

  • 非常感谢,现在我知道出了什么问题,我也知道如何解决了——我只是用列表遍历它,我没有添加任何东西,所以我可以保留原始类型的集合以及迭代过程中的所有内容,如下所示: for (Number n : doubles)
【解决方案2】:

您尝试做的事情是不安全的。考虑这个简单的例子:

import java.util.*;

class SomeBaseClass
{
}

class SomeSubClass extends SomeBaseClass
{
    public static void main(String[] a)
    {
        List<SomeSubClass> orig = new ArrayList<SomeSubClass>();
        // Compiles with no warnings.  This is the purpose of the ? extends syntax
        List<? extends SomeBaseClass> l1 = orig;
        // This is what you're trying to do
        List<SomeBaseClass> l2 = (List<SomeBaseClass>) l1;
        // Then, we add a SomeBaseClass to the new list
        l2.add(new SomeBaseClass());
        // ClassCastException, since this casts a SomeBaseClass to a SomeSubClass
        SomeSubClass first = orig.get(0);
    }
}

【讨论】:

    【解决方案3】:

    你在低调,这是一种不好的做法。尝试重构您的代码以避免这种转换。当然,在这种情况下,您不应该禁止显示警告。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 2015-05-03
      相关资源
      最近更新 更多