aai*_*zza 8 java eclipse ecj java-9 eclipse-neon
我一直在使用新的Eclipse Neon,我的一些代码开始直接给我错误.
这是很奇怪,我在第一,但后来我发现这里的霓虹灯欧洲法院(Eclipse的Java编译器)采用JDK 9提前释放编译器的态度.
我没有遇到该链接中的相同问题,而是我将在此解释的另一个问题.
这是一个测试类,它在Eclipse Neon,JDK 9编译器和JDK 8编译器(不是以前版本的Eclipse)中给出了编译错误.
public class Weird
{
private final Function<String, String> addSuffix =
text -> String.format( "%s.%s", text, this.suffix );
private final String suffix;
public Weird( String suffix )
{
this.suffix = suffix;
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于上面的代码,在所述误差线4为suffix是:
????????????????????????????????????????????????????????????
? Compiler ? Error ?
????????????????????????????????????????????????????????????
? ECJ ? Cannot reference a field before it is defined ?
? JDK 9 ? error: illegal forward reference ?
????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
现在看看我动什么相同类别发生suffix字段声明之前的的addSuffix声明.
public class Weird
{
private final String suffix;
private final Function<String, String> addSuffix =
text -> String.format( "%s.%s", text, this.suffix );
public Weird( String suffix )
{
this.suffix = suffix;
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于上面的代码,在所述误差线6为suffix是:
?????????????????????????????????????????????????????????????????????????
? Compiler ? Error ?
?????????????????????????????????????????????????????????????????????????
? ECJ ? The blank final field suffix may not have been initialized ?
? JDK 9 ? error: variable suffix might not have been initialized ?
?????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
这在JDK 8中运行得非常好; 突然执行似乎是一件奇怪的事情.特别是考虑到已经有编译时检查,以确保正确实例化最终字段.
因此,在addSuffix访问函数时,需要有一个适当的值suffix (null或者另一个故事).
我还会注意到我已经尝试了以下代码,它可以很好地编译JDK9和ECJ:
public class Weird
{
private final String suffix;
private final Function<String, String> addSuffix =
new Function<String, String>()
{
@Override
public String apply( String text )
{
return String.format( "%s.%s", text, suffix );
}
};
public Weird( String suffix )
{
this.suffix = suffix;
}
}
Run Code Online (Sandbox Code Playgroud)
似乎在JDK 9中,匿名类声明和Lambda表达式之间存在很大差异.因此,在这种情况下,我们得到编译器错误,至少ECJ准确地模仿JDK 9编译器.
这个让我感到很惊讶,因为我无法想到为什么编译器会解释这个问题与代码中Generic的含义不同:
public class Weird
{
public void makePDFnames( String [] names )
{
final List<String> messages = Arrays.asList( "nice_beard", "bro_ski" );
final List<String> components = messages.stream()
.flatMap( s -> Stream.of( s.split( "_" ) ) )
.collect( Collectors.toList() );
}
}
Run Code Online (Sandbox Code Playgroud)
此代码提供以下错误:
????????????????????????????????????????????????????????????????????????????????????
? Compiler ? Error ?
????????????????????????????????????????????????????????????????????????????????????
? ECJ ? Type mismatch: cannot convert from List<Serializable> to List<String> ?
? JDK 9 ? NO ERROR. Compiles fine! ?
????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
根据这些信息,在这种情况下,ECJ因错误地模仿JDK 9而出现错误,并且只是一个Eclipse错误.
首先,如果您阅读了您链接的错误报告,ECJ不会"采用JDK 9编译器的态度".两个编译器都有一个错误,其中一个在JDK 9中修复,另一个在Neon中修复.
在Eclipse Mars和Java 8中,lambda字段无法为我编译.它非常有意义,因为它可能违反了final字段的不变性保证.令人惊讶的是,匿名子类成功编译.考虑这个例子:
public static class Weird
{
private final String suffix;
private final Function<String, String> addSuffix = new Function<String, String>() {
@Override
public String apply(String text) {
return String.format( "%s.%s", text, suffix );
}
};
public final String s = addSuffix.apply("1");
public static void main(String[] args) {
System.out.println(new Weird("p").s);
// 1.null (!!)
}
}
Run Code Online (Sandbox Code Playgroud)
我怀疑上述可能是两个编译器中的错误.
至于流错误,同样的代码也在Java 8中编译.所以它可能只是另一个ECJ错误,与Java 9无关.
可能相关:
| 归档时间: |
|
| 查看次数: |
480 次 |
| 最近记录: |