让我举一个简单的例子:
public class Main {
public static abstract class Food {
}
public static abstract class Fruit extends Food {
public String getJuice(){
return "juice";
}
}
public static abstract class Container<T extends Food> {
private T food;
public final T get(){
return food;
}
}
public static abstract class Crate<T extends Fruit> extends Container<T> {
}
public static void Bar(Crate crate) {
Food f = crate.get(); //compiles fine
//Fruit f2 = crate.get(); //can't compile
}
}
当给出原始类型时,crate.get()
会返回Food
而不是Fruit
Crate
被声明为Crate<T extends Fruit> extends Container<T>
,因此禁止Crate<Food>
。 我只是好奇:为什么方法T get()
不会返回Fruit
?为什么需要Crate<Fruit>
?
答案 0 :(得分:5)
这是因为get
声明了Container
。使用原始类型Crate
时,public T get()
对其所有(继承)方法都有效,public Food get()
的签名将被删除为T
,因为{ {1}}在其声明类中的上限为Food
。
虽然Crate
缩小了T
的上限,这恰好是get
的返回类型,但它不会覆盖该方法。如果是这种情况,您会看到不同的行为:
public static abstract class Container<T extends Food> {
private T food;
public T get() {
return food;
}
}
public static abstract class Crate<T extends Fruit> extends Container<T> {
@Override
public T get() {
return super.get();
}
}
public static void bar(Crate crate) {
Food f = crate.get(); // compiles fine
Fruit f2 = crate.get(); // also compiles
}
现在,public T get()
已被删除为public Fruit get()
,因为它已在T
的上限为Fruit
的类中重新声明。