Java 额外的类型参数可以避免无效的覆盖错误吗?

Java 额外的类型参数可以避免无效的覆盖错误吗?,java,generics,Java,Generics,我有一个像 public interface AnInterface { Consumer<Object> getConsumer(); } 公共接口接口{ 消费者获取消费者(); } 还有一个实现类,比如 public class AClass implements AnInterface { @Override public Consumer<String> getConsumer() { return System.out

我有一个像

public interface AnInterface {
    Consumer<Object> getConsumer();
}
公共接口接口{
消费者获取消费者();
}
还有一个实现类,比如

public class AClass implements AnInterface {
    @Override
    public Consumer<String> getConsumer() {
        return System.out::println;
    }
}
public类AClass实现一个接口{
@凌驾
公共消费者{
返回系统.out::println;
}
}
由于
使用者
未扩展
使用者
,因此此(正确)未编译

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

<T> Consumer<Object> getConsumer();
Consumer getConsumer();
这是怎么回事


JDK 1.8 u20中的javac和Luna中的Eclipse编译器都会出现这种情况。

当您添加类型参数
时,代码编译的原因是,在这种情况下,您重写了原始
getConsumer()
方法,即您没有重新定义类型参数(
),而是忽略了它

值得一提的是,在扩展原始类或重写原始方法时,整个泛型信息被忽略,这意味着在这种情况下,编译器将不会验证重写方法(
)的类型参数是否与抽象方法(
)的类型参数兼容.

如果将该方法保持为泛型,则它将如下所示:

@Override
public <T> Consumer<String> getConsumer() {
   ...
}
@覆盖
公共消费者{
...
}

然后编译器将更正并引发编译时错误。

您应该这样编写:

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

public class AClass implements AnInterface<String> {
    @Override
    public Consumer<String> getConsumer {
        return System.out::println;
    }
}
公共接口接口{
消费者获取消费者();
}
公共类AClass实现了一个接口{
@凌驾
公众消费者{
返回系统.out::println;
}
}

是的,这是正确的方法,但这并不能真正解决另一个表单为什么工作……这就是我的答案试图做到的:)我认为可能会发生类似的事情,但我感到困惑,因为我的类没有真正实现接口,这难道不是一个错误吗?你有没有链接到更多关于它是如何工作的信息?等等,它是如何生的?它似乎是具体绑定的。@Makoto,如果一个方法定义了一个类型参数(不管返回类型是否为泛型),那么它就是泛型的。当接口的抽象方法定义了一个类型参数,但实现方法并不关心它(即忽略它),那么实现方法就是原始的。当一个方法被认为是原始的时,编译器就会忽略整个泛型信息(包括返回类型中的信息)。但请注意,这不适用于只返回泛型类型而不实现其他方法的方法。@takteek,checkout。你会在那里得到很多!谢谢你提出了一个非常好的问题。奇怪的是,它一开始并没有编译,你应该能够用更具体的类型覆盖它,作为对原始类型@Hurda的扩展(可赋值),这是不一样的。@kocko现在我看到了不同之处,但这应该是一样的:-)泛型的另一个限制。。。