gpt4 book ai didi

java - 静态方法和继承的返回类型中的泛型

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:02:55 26 4
gpt4 key购买 nike

静态方法的返回类型中的泛型似乎与继承相处得不好。请看下面的代码:

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());
}
}

我试图通过更改 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());
}
}

对静态方法进行如此严格检查的原因是什么?我该如何相处?更改方法名称似乎很尴尬。

最佳答案

B中的静态方法并没有覆盖A中的静态方法而是隐藏了它。 JLS 8.4.8.3明确指出返回类型必须是可替换的,否则将无法编译:

If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type-substitutable (§8.4.5) for d2, or a compile-time error occurs.

可替代性在 JLS #8.4.5 中定义:

A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:

  • [...]
  • If R1 is a reference type then:
    • R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or
    • 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;
}

关于java - 静态方法和继承的返回类型中的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13533233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com