JDK 7中的类型推断比JDK 6更具限制性吗?
我认为这可能与为什么List的通用演员有关? 扩展Set ..>到List 在Sun JDK 6上成功但在Oracle JDK 7上无法编译?
如果我们采用以下类,它们在JDK 6下编译正常:
public final class Foo { private final V value; private Foo(final V value) { this.value = value; } public static Foo of(final R value) { return new Foo(value); } } final class Tester { @Test(groups="unit") public static void test() { bar(Foo.of(BigDecimal.ZERO)); // This line fails in JDK 7 but not JDK 6 } private static void bar(final Foo target) { assert target != null; } }
但是,在JDK 7下,我收到以下错误:
[ERROR] \work\fsb-core\src\test\java\com\fsb\core\Foo.java:[42,8] error: method bar in class Tester cannot be applied to given types;
我认为类型推断在JDK 7中的限制性较小(例如,添加构造函数推断)。但是,这里,编译器拒绝在JDK 6下有效的类型。
这是一个错误吗? 或者推理的规则是否对方法更加严格?
严格按照规范, T
不能推断(每15.12.2.7),所以它应该被视为Object
。
这可以被视为规范的失败。 这是规则推断R
:首先是约束R :> BigDecimal
,其中:>
means 是一个超类型 。 推理规则然后选择R=BigDecimal
因为它是满足约束的最具体类型。
现在,由于T:>R
, T:>BigDecimal
,人们会认为这也应该产生T=BigDecimal
。
不幸的是,推理规则不考虑T:>R
T
没有任何禁忌。 T
不是通过相同的原理推断的。
虽然很糟糕,但规格是规格。 你的代码不应该编译。 那里的Javac6错了。
在Java 8中,推理规则有了很大的改进,使lambda表达式更易于使用。 希望您的代码应该在Java 8中编译。