下限通配符在javac中会引起麻烦,但在Eclipse中不会

下限通配符在javac中会引起麻烦,但在Eclipse中不会,java,eclipse,generics,java-8,javac,Java,Eclipse,Generics,Java 8,Javac,这段代码可以在Eclipse中编译,但不能在javac中编译: import java.util.function.Consumer; 公开课考试{ 公共静态最终无效m1(消费者c){ m2(c); } private static final void m2(Consumer此代码是合法的wrt JLS 8。javac版本8和更早版本在处理通配符和捕获方面有几个错误。从版本9开始(早期访问,我尝试了版本ea-113和更高版本),javac也接受此代码 为了理解编译器是如何根据JLS分析的,有必

这段代码可以在Eclipse中编译,但不能在javac中编译:

import java.util.function.Consumer;
公开课考试{
公共静态最终无效m1(消费者c){
m2(c);
}

private static final void m2(Consumer此代码是合法的wrt JLS 8。javac版本8和更早版本在处理通配符和捕获方面有几个错误。从版本9开始(早期访问,我尝试了版本ea-113和更高版本),javac也接受此代码

为了理解编译器是如何根据JLS分析的,有必要区分什么是通配符捕获、类型变量、推理变量等等

c
的类型是
Consumer
(javac将编写
Consumer
)。此类型未知,但已修复


m2
的参数具有类型
使用者→ 消费者注意,可以毫无问题地编译以下内容:

public class Test {
    public static final void m1(Consumer<?> c) {
        m2(c);
    }
    private static final <T> void m2(Consumer<T> c) {
    }
}
没有编译器对象会显示该属性

当您将通配符替换为命名类型时,也将接受该通配符,例如

public class Test {
    public static final void m1(Consumer<?> c) {
        m2(c);
    }
    private static final <E,T extends E> void m2(Consumer<E> c) {
    }
}
公共类测试{
公共静态最终无效m1(消费者c){
m2(c);
}
专用静态最终空隙m2(用户c){
}
}
这里,
E
T
的超级类型,就像
?super T
一样

我试图找到与此场景最接近的
javac
的bug报告,但是当涉及到
javac
和通配符类型时,它们太多了,我最终放弃了。免责声明:这并不意味着有这么多bug,只是报告了这么多相关的场景,可能都有不同的症状同样的错误


唯一重要的是,它已经在Java 9中得到了修复。

甚至早在9b29版本的Java C也可以编译它。非常感谢您对此进行了深入的研究。很高兴看到Java 9中,这两个编译器现在的行为是相同的!:)我也非常欣慰地看到这种融合:)
public class Test {
    public static final void m1(Consumer<?> c) {
        m2(c);
    }
    private static final <E,T extends E> void m2(Consumer<E> c) {
    }
}