Axe*_*xel 6 java generics inheritance static-methods
返回类型的静态方法中的泛型似乎与继承相处得不好.请看下面的代码:
class ClassInfo<C> {
public ClassInfo(Class<C> clazz) {
this(clazz,null);
}
public ClassInfo(Class<C> clazz, ClassInfo<? super C> superClassInfo) {
}
}
class A {
public static ClassInfo<A> getClassInfo() {
return new ClassInfo<A>(A.class);
}
}
class B extends A {
// Error: The return type is incompatible with A.getClassInfo()
public static ClassInfo<B> getClassInfo() {
return new ClassInfo<B>(B.class, A.getClassInfo());
}
}
Run Code Online (Sandbox Code Playgroud)
我试图通过更改A.getClassInfo()的返回类型来规避这一点,现在错误弹出另一个位置:
class ClassInfo<C> {
public ClassInfo(Class<C> clazz) {
this(clazz,null);
}
public ClassInfo(Class<C> clazz, ClassInfo<? super C> superClassInfo) {
}
}
class A {
public static ClassInfo<? extends A> getClassInfo() {
return new ClassInfo<A>(A.class);
}
}
class B extends A {
public static ClassInfo<? extends B> getClassInfo() {
// Error: The constructor ClassInfo<B>(Class<B>, ClassInfo<capture#1-of ? extends A>) is undefined
return new ClassInfo<B>(B.class, A.getClassInfo());
}
}
Run Code Online (Sandbox Code Playgroud)
这种严格检查静态方法的原因是什么?我怎么能相处?更改方法名称似乎很尴尬.
B中的静态方法不会覆盖A中的静态方法,但会将其隐藏.该JLS 8.4.8.3明确地说,返回类型必须是替代,否则将无法编译:
如果具有返回类型R1的方法声明d1覆盖或隐藏具有返回类型R2的另一个方法d2的声明,则对于d2,d1必须是return-type-substitutable(第8.4.5节),否则会发生编译时错误.
可替代性在JLS#8.4.5中定义:
返回类型为R1的方法声明d1是返回类型 - 可替代另一个返回类型为R2的方法d2,当且仅当以下条件成立时:
- [...]
- 如果R1是引用类型,则:
- R1是R2的子类型,或者R1可以通过未经检查的转换(第5.1.9节)转换为R2的子类型,或者
- R1 = | R2 |
在你的情况下:d1是B中的方法,R1是ClassInfo<B>,d2是A和R2中的方法ClassInfo<A>.而ClassInfo<B>不是一个亚型ClassInfo<A>.
但是,ClassInfo<? extends B>可以转换为ClassInfo<? extends A>.您可以在以下位置观察该行为:
void someMethod(){
ClassInfo<B> b1 = (ClassInfo<B>) get1(); //does not compile
ClassInfo<? extends B> b2 = (ClassInfo<? extends B>) get2(); //compiles
}
ClassInfo<A> get1() {
return null;
}
ClassInfo<? extends A> get2() {
return null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1660 次 |
| 最近记录: |