长期的Java类型检查错误"扩展"链

时间:2014-07-05 11:18:53

标签: java typechecking

我对Java类型检查感到有些困惑:

我有一个声明为:

的静态方法
public static void register(EClass eClass, Class<? extends Page<EObject>> pClass) { ... }

我称之为:

Page.register(HyconmdePackage.Literals.STATION, StationPage.class);

第二个参数被声明为(忘记第一个参数:它没问题):

public class StationPage extends Page<Station> { ...
public abstract class Page<O> { ...
public interface Station extends Identifiable { ...
public interface Identifiable extends EObject { ...

但是我收到了错误:

The method register(EClass, Class<? extends Page<EObject>>) in the type Page is not applicable for the arguments (EClass, Class<StationPage>)

我还尝试将Page声明为:

public abstract class Page<O extends EObject> { ...

但错误仍然存​​在,我在课程页面中还有其他问题。

我的错误是什么? (我希望这足以猜出这个问题;将程序缩小到适当大小以获得一个有效的例子并不是一项简单的任务)

TIA

2 个答案:

答案 0 :(得分:2)

StationPage扩展了Page<Station>,但您的方法签名要求它扩展Page<EObject>

请注意,即使Station(间接)延伸EObject,但这并不意味着Page<Station>延伸Page<EObject>。因此,如果需要Page<Station>,则无法使用Page<EObject>

声明这样的方法:

public static void register(EClass eClass,
    Class<? extends Page<? extends EObject>> pClass)

你当然也可以使用类型参数而不是通配符:

public static <P extends Page<E>, E extends EObject> register(EClass eClass,
    Class<P> pClass)

答案 1 :(得分:1)

简单。 Page<Station>不被视为延长Page<EObject>。再次检查oracle.com上的泛型教程

要查看我的意思,请查看如果Page<Station>被视为扩展Page<EObject>

,此代码将如何运作
public void addItem(Page<EObject> page, EObject item) {
  page.add(item);
  ...
}

addItem(new StationPage(), new EObject());

这会导致错误,因为您试图将EObject传递给期望Station的方法。由于在运行时未使用泛型信息,因此JVM无法识别这样的错误。因此,编译器必须将其解释为编译错误,而StationPage不会从Page<Object>扩展

使用Jesper指示的泛型

public void addItem(Page<? extends EObject> page, EObject item) {

将允许编译,但会对您可能与page参数一起使用的操作类型设置限制(它不允许调用page.addItem,完全针对相同的动机)。< / p>