<T extends Foo>
定义一个类型,该类型T
必须是 的某个子类型Foo
。这实际上并没有在one
or中的任何地方使用two
。
我的猜测是这是因为编译器如何擦除函数的类型的处理方式不同,因为有一个泛型类型定义范围为one.function1()
.
查看JLS 8.4.8.3定义了有效的方法覆盖。有一个关于“未经检查的转换”警告的例子。在那里,它链接到8.4.5描述什么是“return-type-substitutable”,并从那里链接到5.1.9关于未经检查的转换。
我没有答案,但似乎将该方法标记为泛型方法(不仅仅是使用参数化类型的方法)触发允许进行未经检查的转换 - 无论是有意还是由于错误。
编辑:给定
public class Main {
class Bar<X> {}
class Foo{}
class one{
public <T extends Foo> Bar<Foo> function1() { return null; }
public Bar<Foo> function2(){ return null; }
}
class two<F extends Foo> extends one{
public Bar<F> function1(){ return null; } //Doesn't throw an error
public Bar<F> function2(){ return null; } //Throws an error
}
}
编译javac -Xlint:unchecked Main.java
:
Main.java:9: warning: [unchecked] function1() in Main.two overrides <T>function1() in Main.one
public Bar<F> function1(){ return null; } //Doesn't throw an error
^
return type requires unchecked conversion from Main.Bar<F> to Main.Bar<Main.Foo>
where F,T are type-variables:
F extends Main.Foo declared in class Main.two
T extends Main.Foo declared in method <T>function1()
Main.java:10: error: function2() in Main.two cannot override function2() in Main.one
public Bar<F> function2(){ return null; } //Throws an error
^
return type Main.Bar<F> is not compatible with Main.Bar<Main.Foo>
where F is a type-variable:
F extends Main.Foo declared in class Main.two
1 error
1 warning