【问题标题】:Unchecked cast from generic type to the same type从泛型类型到相同类型的未经检查的强制转换
【发布时间】:2020-02-11 09:20:38
【问题描述】:

以下代码在 IntelliJ IDEA 中生成警告 Unchecked cast: 'T' to 'U':

interface A {}
class B<T extends A, U extends A> {
    void f() {
        final T t = null;
        final U u = (U) t;
    }
}

这对我来说没有意义,因为 T 和 U 被定义为相同的类型。有什么问题?

【问题讨论】:

  • T extends A, U extends A 并不意味着T 和U 是同一类型。

标签: java generics unchecked-cast


【解决方案1】:

T 和 U 未定义为同一类型。它们都定义为extends A,这意味着T 和U 可以是实现A 接口的无关类。因此演员阵容并不安全。

您可以做的唯一安全转换是将T 或U 类型的引用转换为A 类型。当然,你不需要这样的演员表。您可以简单地将它们分配给A 类型的变量。

【讨论】:

  • 谢谢,但我还是不明白为什么。 T 和 U 都扩展了 A,那么为什么我不能从“扩展 A 的类型”转换为“扩展 A 的另一种类型”?前后,演员表对象将扩展A。
  • @Nickkk Integer 和 String 都实现了 Serializable;但是您不会期望能够将Integer 转换为String,对吧?
  • 这个例子做到了。我认为T 和U 类型与A 相同,但T extends A 是特定类型的占位符。谢谢!
【解决方案2】:

家长:

interface A {
} 

孩子:

class B implements A {

}

class C implements A {

}

在上面的例子中,A 是父母 B 和 C。

例子:

下面的代码可以正常工作。

  A a = new B();

  B b = (B)a;

这将触发类 Cast Exception。

  B b = new B();

  C c = (C) b;

您不能使用 Siblings 类型进行类型转换。这是因为您可能会尝试访问结果类中可能存在的方法/属性。

String、Integer、Object 也一样。对象是父级
Integer 和 String 是 Object 类的子类,但您不能强制转换这些类。

【讨论】:

    【解决方案3】:

    虽然T 和U 都扩展A,但它们不是同一类型。因此,您不能从一个转换到另一个。

    考虑:

    class D implements A {}
    class E implements A {}
    B<D, E> b;
    

    你不能从 D 转换到 E。

    【讨论】:

      【解决方案4】:
          final T t = null;
          final U u = (U) t;
      

      虽然这没有被选中,但这实际上是安全的,因为null 可以转换为任何没有ClassCastException 的引用类型。

      但是,编译器在您转换它时不会考虑非空引用的值:它只是“一些”T。这是程序员比编译器更了解类型的示例,因为您知道t == null,因此您可以通过添加强制转换和@SuppressWarnings 合法地要求编译器信任您。

      但如果t 不为空,这并不总是安全的。 T 和 U 是不同的类型:它们是“扩展 A 的东西”和“扩展 A 的东西(可能相同,可能不一样)”。

      为了更具体一点,这里有一个等效的例子:

      class B<T extends Serializable, U extends Serializable> {
        U method(T t) {
          return (U) t;
        }
      }
      
      String s = new B<Integer, String>().method(1);
      

      这将因ClassCastException 而失败,因为Integer 不是String。

      如果您不希望它们是不同的类型,请删除其中一个(当然还有演员表)。

      【讨论】:

        猜你喜欢
        • 2015-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多