错误的通用返回类型

时间:2014-01-25 18:10:37

标签: java generics

让我举一个简单的例子:

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>

1 个答案:

答案 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的类中重新声明。