繁体   English   中英

从泛型类型到相同类型的未经检查的强制转换

[英]Unchecked cast from generic type to the same type

以下代码在 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;
    }
}

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

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

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

虽然TU扩展了A ,但它们不是同一类型。 因此你不能从一个转换到另一个。

考虑:

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

你不能从 D 投射到 E。

家长:

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 类型进行类型转换。 这是因为您可能会尝试访问可能出现在结果类中的方法/属性。

同样的事情可以是字符串,整数,对象。 对象是对象
Integer 和 String 是 Object 类的子类,但您不能将这些分类。

    final T t = null;
    final U u = (U) t;

尽管这是未经检查的,但这实际上是安全的,因为null可以在没有ClassCastException情况下转换为任何引用类型。

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

但是如果t不为空,这并不总是安全的。 TU有不同的类型:他们是“东西延伸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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM