【问题标题】:Why does this program compile with Java 7 but not Java 8? [duplicate]为什么这个程序用 Java 7 编译而不用 Java 8 编译? [复制]
【发布时间】:2015-09-03 20:05:24
【问题描述】:

考虑这个程序:

public class xx<T> {

    <T> Iterable<T> createIterable(Class<T> cls) {
        return null;
    }

    Iterable<? extends Number> createNumberIterable(boolean floatingPoint) {
        return this.createIterable(floatingPoint ? Integer.class : Float.class);
    }
}

在 Java 7 下编译:

$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
$ javac xx.java
$

在 Java 8 下它不会:

$ java -version
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
$ javac xx.java
xx.java:8: error: method createIterable in class xx<T#2> cannot be applied to given types;
        return this.createIterable(floatingPoint ? Integer.class : Float.class);
                   ^
  required: Class<T#1>
  found: floatingPo[...]class
  reason: inferred type does not conform to equality constraint(s)
    inferred: Float
    equality constraints(s): Float,Integer
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>createIterable(Class<T#1>)
    T#2 extends Object declared in class xx
1 error
$

这是真的:

  1. 这是 Java 7 中的错误,已在 Java 8 中得到修复(编译器过于宽松);或
  2. 这是 Java 8 中引入的一个新错误

如果答案是 #1,您能否用普通语言解释 JLS 不允许这样做的原因,使用明显的解释?

(注意:请不要解释如何解决问题,这不是问题)

【问题讨论】:

标签: java javac jls


【解决方案1】:

旧行为既不是错误,新行为也不是错误。条件表达式类型的规则变得更加复杂,这在很多情况下都有帮助,而且对您的情况并没有真正的伤害。

编译器不允许这样做,因为Integer.class 和Float.class 的类型无法比较。没有类型 T 会使 Class&lt;T&gt; 成为 Class&lt;Integer&gt; 和 Class&lt;Float&gt; 的超类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 2014-12-03
    • 1970-01-01
    • 2018-12-02
    • 2016-10-31
    • 2014-09-26
    相关资源
    最近更新 更多