Java 转换为泛型类的泛型子类型

Java 转换为泛型类的泛型子类型,java,generics,casting,subclass,Java,Generics,Casting,Subclass,假设我有这个: class Base<T> {} class Derived<T> extends Base<T> {} 类基类{} 类派生扩展基{} 然后在我的代码中,我可以安全地在没有警告的情况下进行强制转换,如下所示: public <T> void foo(Base<T> base) { Derived<T> f = (Derived<T>) base; // fine, no warnin

假设我有这个:

class Base<T> {}

class Derived<T> extends Base<T> {}
类基类{}
类派生扩展基{}
然后在我的代码中,我可以安全地在没有警告的情况下进行强制转换,如下所示:

public <T> void foo(Base<T> base) {
    Derived<T> f = (Derived<T>) base; // fine, no warning
}
public void foo(基本){
派生f=(派生)基;//很好,没有警告
}
这很好。但是,如果派生类具有更多类型参数,它将不再工作:

class Base<T> {}

class Derived<T, U> extends Base<T> {}

public <T> void foo(Base<T> base) {
    Derived<T, ?> f = (Derived<T, ?>) base; // unchecked warning!
}
类基类{}
类派生扩展基{}
公共void foo(基本){
派生f=(派生)基;//未选中警告!
}

为什么呢?这里有什么明显的我遗漏的吗?

这对我来说似乎是个错误。发件人:

未选中从类型S到参数化类型(§4.5)T的强制转换 除非以下至少一个条件成立:


  • 这就是为什么它不起作用?它对我有效…什么“不起作用”是我得到了一个未检查的警告,尽管这个强制转换是完全安全的。什么编译器?我在Eclipse编译器中看到了它。您使用的是什么Java版本/IDE?对于Java 6 u 37和Intellij IDEA 12.1,我没有收到任何未经检查的警告。我犹豫是否发布这个答案,因为Eclipse编译器在泛型方面有着良好的记录,在Eclipse中看到这个警告让我觉得我遗漏了一些东西。如果我误读了JLS,请评论或编辑我的答案以确保正确性。JDK 7不会发出警告。JLS 5/6没有强制要求发出警告。我认为jdt编译器开发人员只是因为错误而错过了更改或忽略了它(应该是:“…除了T以外没有其他子类型X,其中| T |=| X |和…”BenSchulz是的,我自己也在想这个措辞-是否有JLS问题报告了?我不知道,但这些都不可能追踪到如此微小的技术细节。