sie*_*egi 8 java javac eclipse-jdt java-8
注意:我发现了多个问题,指出了javacEclipse编译器之间的差异,但据我所知,所有这些问题都讨论了其他问题.
假设我们有这个方法:
public static <T, U> void foo(Supplier<T> a, Function<T, U> b, Consumer<U> c)
{
c.accept(b.apply(a.get()));
}
Run Code Online (Sandbox Code Playgroud)
javac在编译对此方法的调用时,我发现Eclipse Java编译器与Eclipse Java编译器之间存在不同的行为,我不确定哪两个是正确的.
这种方法的简单用法可能是:
// variant 1
foo(
() -> Optional.of("foo"),
value -> value.get(),
value -> System.out.println(value));
Run Code Online (Sandbox Code Playgroud)
编译器应该能够结合T到Optional<String>使用所述第一参数,并U以String使用所述第二.所以这个电话应该是有效的(在我看来).
这可以很好javac地编译,但无法使用Eclipse进行编译:
类型不匹配:无法从void转换为<unknown>
在第一个参数(() -> Optional.<String> of("foo"))中添加一个类型参数也使它在Eclipse中编译.
问题:从规范的角度来看,Eclipse是否正确拒绝此调用(以及为什么(不))?
现在假设我们想抛出一个自定义(运行时)异常,如果它Optional是空的:
// variant 2
foo(
() -> Optional.of("foo"),
value -> value.orElseThrow(() -> new RuntimeException()),
value -> System.out.println(value));
Run Code Online (Sandbox Code Playgroud)
这javac和Eclipse编译器都拒绝了,但是有不同的错误消息:
javac:"未报告的异常X;必须被捕获或声明被抛出"当我将type参数添加到第一个参数时,Eclipse成功编译但javac仍然失败.当我将<RuntimeException>第二个参数添加为类型参数时,反之亦然,Eclipse失败并javac成功.
问题:再次,编译器是否正确拒绝此调用以及为什么?
在我看来,两个变体应该编译正常,没有使用类型参数的额外提示.如果是这样,我将填写一个错误报告javac(关于"未报告的异常")和一个关于Eclipse编译器的错误报告(关于"类型不匹配").但首先我想确定规范与我的观点一致.
使用的版本:
javac:1.8.0_66编辑:
我在Eclipse中填写了错误482781.
问题javac已经报告为JDK-8056983,请参阅Tunakis的回答.
是的,你在每个方面都是正确的.老实说,我无法链接到JLS的特定行:类型推断是一整章.
免责声明:我使用Eclipse Mars 4.5.1和JDK 1.8.0_60进行了测试.
Variant 1应该编译,Eclipse在这里有一个bug.我在他们的Bugzilla中找不到与此相关的任何内容,因此您可以继续进行归档.你可以向自己保证,如果你将你的例子减少到它,它应该编译:
public static <T> void foo(Supplier<T> a) {
a.get();
}
foo(() -> Optional.of("foo"));
Run Code Online (Sandbox Code Playgroud)
用Eclipse和Eclipse编译都很好javac.添加参数确实(应该)不会更改T编译期间推断的类型.
变量2不编译javac,这确实是一个错误,如JDK-8056983中所报告的.编译器应该能够推断出它X是RuntimeException.至于为什么Eclipse仍然无法编译,再次,我在他们的Bugzilla中找不到任何东西,所以随时报告这个!
| 归档时间: |
|
| 查看次数: |
509 次 |
| 最近记录: |