以下Java代码不会生成未经检查的强制转换警告(使用Java 8的Eclipse编译器进行测试):
class Parent<T> {}
class Child<T> extends Parent<T> {}
class Test {
<T> void test() {
Parent<T> p = new Child<T>();
// cast accepted by compiler:
Child<T> cast = (Child<T>)p;
}
}
因此,我了解编译器必须以某种方式意识到,如果p
既是Parent<T>
(根据编译时类型)又是Child
(根据运行时类型),那么可以安全地假设它是Child<T>
,因为Child
在其extends
子句中传递了类型参数。
但是,以下类似代码会生成未经检查的强制转换警告:
class Parent<T> {}
class Child<T, U> extends Parent<T> {}
class Test {
<T, U> void test() {
Parent<T> p = new Child<T, U>();
// cast considered unsafe by compiler:
Child<T, ?> cast = (Child<T, ?>)p;
}
}
但是,考虑第一个示例安全性的理由也应在此处适用!如果p
是Parent<T>
和Child
,那么在给定Child<T, ?>
的{{1}}子句的情况下,它应该是Child
!
(请注意,我没有在转换中包含extends
,因为在编译时或运行时都无法检查。)
是否可以在没有警告的情况下转换为具有附加参数的子类型?
答案 0 :(得分:0)
正如我在评论中说的那样,Oracle的Java 1.8.0_112编译器中的这两个转换工作可能是编译器错误或限制(如果您愿意)。
我猜这两种类型的转换都不应遵循不安全的原则,即假设Subclassing类是正确的类(即实例确实是Child
),如果它与Child<T, ?>
兼容,则必须正确它是Parent<T>
。相反,如果您尝试将其强制转换为Child<U, V>
之类的东西,其中U
不能保证为T
或V
的话,它将无法正常工作(即发出警告)但是?
,因为有些Parent<T>
的孩子不一定是Child<U, V>
。