简体   繁体   English

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

[英]Extra type parameter avoids invalid override error?

I have an interface like 我有一个像

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

And an implementation class like 还有一个实现类

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

This (correctly) does not compile since Consumer<String> does not extend Consumer<Object> . 由于Consumer<String>不扩展Consumer<Object>因此(正确)无法编译。

However, if I change the interface to have an extra, unused type parameter on getConsumer, the error goes away and it compiles fine: 但是,如果我将接口更改为在getConsumer上具有一个额外的未使用的类型参数,则该错误消失并且可以正常编译:

<T> Consumer<Object> getConsumer();

What's going on here?! 这里发生了什么?!

This occurs with javac in JDK 1.8 u20 and the Eclipse compiler in Luna. 这在JDK 1.8 u20中的javac和Luna中的Eclipse编译器中会发生。

The reason the code compiles, when you add the type parameter <T> , is that in this case you're overriding the raw getConsumer() method, ie you are not re-defining a type parameter ( <T> ), but you're just ignoring it. 添加类型参数<T>时代码编译的原因是,在这种情况下,您将覆盖原始的 getConsumer()方法,即,您没有在重新定义类型参数( <T> ),但是只是无视它。

It's worth mentioning that when extending raw classes or overriding raw methods, the whole generic information is just ignored, which means that in this case the compiler will not verify if the type parameter of the overriding method ( <String> ) is compatible with the type-parameter of the abstract method ( <Object> ). 值得一提的是,在扩展原始类或覆盖原始方法时, 整个通用信息将被忽略,这意味着在这种情况下,编译器将不会验证覆盖方法( <String> )的类型参数是否与该类型兼容-抽象方法的参数( <Object> )。

If you had kept the method as generic, it would look like: 如果您将方法保留为通用方法,则它将类似于:

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

and then the compiler would correct raise a compile-time error. 然后编译器将正确地引发一个编译时错误。

you should write like this: 您应该这样写:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM