额外的类型参数避免了无效的覆盖错误?

时间:2015-10-17 21:41:29

标签: java generics

我有一个像

这样的界面
public interface AnInterface {
    Consumer<Object> getConsumer();
}

这样的实现类
public class AClass implements AnInterface {
    @Override
    public Consumer<String> getConsumer() {
        return System.out::println;
    }
}

由于Consumer<String>未扩展Consumer<Object>,因此(正确)无法编译。

但是,如果我将接口更改为在getConsumer上有一个额外的,未使用的类型参数,则错误消失并且编译正常:

<T> Consumer<Object> getConsumer();

这里发生了什么?!

这发生在JDK 1.8 u20中的javac和Luna中的Eclipse编译器中。

2 个答案:

答案 0 :(得分:3)

当您添加类型参数<T>时,代码编译的原因是,在这种情况下,您将覆盖原始 getConsumer()方法,即您不是重新定义一个类型参数(<T>),但你只是忽略它。

值得一提的是,在扩展原始类或覆盖原始方法时,只会忽略 整个 泛型信息,这意味着在这种情况下编译器不会验证是否覆盖方法的类型参数(<String>)与抽象方法的类型参数(<Object>)兼容。

如果方法保留为通用方法,它将如下所示:

@Override
public <T> Consumer<String> getConsumer() {
   ...
}

然后编译器会纠正引发编译时错误。

答案 1 :(得分:0)

你应该这样写:

public interface AnInterface<T> {
    Consumer<T> getConsumer();
}

public class AClass implements AnInterface<String> {
    @Override
    public Consumer<String> getConsumer {
        return System.out::println;
    }
}