有界的通配符没有编译

时间:2015-09-18 15:55:19

标签: java generics

我有这样的代码:

interface InterfaceA { ... }

interface InterfaceB { ... }

class ClassA {
    public void methodA(Class<? extends InterfaceB> clazz) { ... }
}

class ClassB<P extends InterfaceA & InterfaceB> {
    public void methodB(P p) {
        new ClassA().methodA(p.getClass());
    }
}

问题是:为什么编译器不允许将p.getClass()作为参数传递给方法methodA - 错误消息是:

The method methodB(Class<? extends InterfaceB>) in the type ClassA is not applicable for the arguments (Class<capture#1-of ? extends InterfaceA>)

很明显P类型在InterfaceB中延伸了ClassB,所以我不知道它为什么不起作用。

1 个答案:

答案 0 :(得分:3)

Object#getClass()的返回类型是

  

实际结果类型为Class<? extends |X|>,其中|X|为   擦除getClass所在表达式的静态类型   调用。

删除静态类型p(调用getClass的表达式)是

的擦除
P extends InterfaceA & InterfaceB

InterfaceA。这在关于Type Erasure

的Java语言规范章节中指定
  

类型变量(第4.4节)的擦除是其最左边界的擦除。

您的方法接受Class<? extends InterfaceB>,而不是Class<? extends InterfaceA>。这就是你的样本无法编译的原因。

您可以重新排列边界以使示例工作

class ClassB<P extends InterfaceB & InterfaceA> {