[英]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;
}
}
这对我来说没有意义,因为T
和U
被定义为相同的类型。 问题是什么?
T
和U
未定义为同一类型。 它们都定义为extends A
,这意味着T
和U
可以是实现A
接口的无关类。 因此演员表是不安全的。
您可以做的唯一安全转换是将类型T
或U
引用转换为类型A
。 当然,你不需要这样的演员。 您可以简单地将它们分配给A
类型的变量。
虽然T
和U
扩展了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
不为空,这并不总是安全的。 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
。
如果您不希望它们是不同类型,请删除其中之一(当然还有演员表)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.