Java JDK 7中的类型推断比JDK 6中的更严格?

Java JDK 7中的类型推断比JDK 6中的更严格?,java,generics,type-inference,java-7,Java,Generics,Type Inference,Java 7,我认为这可能与 如果我们使用以下类,它们在JDK 6下编译得很好: public final class Foo<V> { private final V value; private Foo(final V value) { this.value = value; } public static <T, R extends T> Foo<T> of(final R value) { r

我认为这可能与

如果我们使用以下类,它们在JDK 6下编译得很好:

public final class Foo<V> {

    private final V value;

    private Foo(final V value) {

        this.value = value;
    }

    public static <T, R extends T> Foo<T> of(final R value) {

        return new Foo<T>(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<? extends Number> target) {

        assert target != null;
    }
}
我认为类型推断在JDK 7中没有那么严格(例如,添加构造函数推断)。然而,在这里,编译器拒绝了一个在JDK 6下有效的类型


这是虫子吗?还是推理规则对方法更为严格?

严格按照规范,
T
无法推断(根据15.12.2.7),因此应将其视为
对象

这可以被视为规范的失败。这就是规范推断
R
:首先存在约束
R:>BigDecimal
,其中
:>
意味着是的超类型。推理规则然后选择
R=BigDecimal
,因为它是满足约束的最具体的类型

现在,由于
T:>R
T:>BigDecimal
,人们会认为这应该也会产生
T=BigDecimal

不幸的是,推理规则没有考虑
T:>R
T
上没有约束
T
不是通过相同的原理推断出来的

虽然它很糟糕,但spec就是spec。你的代码不应该编译。Javac6在这里是错误的


在Java8中,推理规则有了很大的改进,使lambda表达式更易于使用。希望您的代码能够用Java 8编译。

谢谢您的解释。我感到宽慰的是,类型推断在JDK7中是正确的(虽然有点沮丧,但它只是在JDK6中意外地起作用)。这似乎与:。(最初在.java8(1.8.0_25)中引用)这再次编译得很好。
[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;