添加通用参数

时间:2019-01-14 10:45:31

标签: java generics

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

但是,考虑第一个示例安全性的理由也应在此处适用!如果pParent<T>Child,那么在给定Child<T, ?>的{​​{1}}子句的情况下,它应该是Child

(请注意,我没有在转换中包含extends,因为在编译时或运行时都无法检查。)

是否可以在没有警告的情况下转换为具有附加参数的子类型?

1 个答案:

答案 0 :(得分:0)

正如我在评论中说的那样,Oracle的Java 1.8.0_112编译器中的这两个转换工作可能是编译器错误或限制(如果您愿意)。

我猜这两种类型的转换都不应遵循不安全的原则,即假设Subclassing类是正确的类(即实例确实是Child),如果它与Child<T, ?>兼容,则必须正确它是Parent<T>。相反,如果您尝试将其强制转换为Child<U, V>之类的东西,其中U不能保证为TV的话,它将无法正常工作(即发出警告)但是?,因为有些Parent<T>的孩子不一定是Child<U, V>