Den*_*ner 3 java generics overriding list
我想在java中编译这个代码的一些变体.
class X
{
List<X> getvalue(){...};
}
class Y extends X
{
List<Y> getvalue(){...};
}
Run Code Online (Sandbox Code Playgroud)
Javac(1.6)返回错误,因为List <Y>和List <X>不兼容.
关键是我希望编译器能够识别List <Y>是List <X>的兼容返回类型,如果Y是X的子类型.我想要的原因是简化用户定义工厂的使用类.
注意:这个问题有点像 这个问题, 但对于java.
在Java中,重写方法的返回类型必须与被覆盖的方法的返回类型协变.
该类java.util.List不是协变的(实际上,没有Java类.这是因为缺少声明 - 站点方差注释).换句话说,B <: A并不意味着List<B> <: List<A>(读<:作is-subtype-of).因此,您的代码不会进行类型检查.
在Java中,您有定义 - 站点差异.因此,以下是typechecks:
import java.util.List;
class X {
List<? extends X> getvalue() { return null; }
}
class Y extends X {
List<Y> getvalue() { return null; }
}
Run Code Online (Sandbox Code Playgroud)
不,它不是兼容的类型.你不能转换List<Y>为List<X>只是因为Y是它的子类X.考虑:
List<Banana> bananas = new ArrayList<Banana>();
List<Fruit> fruit = bananas;
fruit.add(new Apple());
Banana banana = fruit.get(0); // But it's an apple!
Run Code Online (Sandbox Code Playgroud)
您可以使用通配符界在Java中表达有限的差异,给一些东西,是有效的:
List<? extends Fruit> fruit = bananas;
Run Code Online (Sandbox Code Playgroud)
因为这会阻止你(在编译时)试图添加任何额外的水果 - 编译器知道它可能是无效的.
我会推荐Angelika Langer的Java Generics FAQ来进一步阅读这类内容.