2

The following code generates a warning Unchecked cast: 'T' to 'U' in IntelliJ IDEA:

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

This doesn't make sense to me, since T and U are defined as the same type. What is the problem?

4

4 回答 4

5

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

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

于 2020-02-11T09:23:20.227 回答
1

家长:

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

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

于 2020-02-11T09:52:18.340 回答
1

虽然两者都TUextend A,但它们不是同一类型。因此,您不能从一个转换到另一个。

考虑:

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

你不能从 D 施法到 E。

于 2020-02-11T09:23:54.670 回答
0
    final T t = null;
    final U u = (U) t;

尽管这是未选中的,但这实际上是安全的,因为null可以转换为任何不带ClassCastException.

但是,编译器在转换时不会考虑非空引用的值:它只是 "some" 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);

这将失败 a ClassCastException,因为 anInteger不是 a String

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

于 2020-02-11T09:36:05.420 回答