为什么该程序可以用Java 7而不是Java 8编译? [英] Why does this program compile with Java 7 but not Java 8?

查看:126
本文介绍了为什么该程序可以用Java 7而不是Java 8编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑此程序:

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下,它会编译:

Under Java 7 it compiles:

$ 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中,它不是:

Under Java 8 it does not:

$ 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不允许这样做的原因吗?

If the answer is #1, can you explain in normal language the reason why the JLS doesn't allow this, using the obvious interpretation?

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

(Note: please don't explain how to workaround the problem, that's not the question)

推荐答案

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

Neither was the old behavior a bug, nor is the new behavior a bug. The rules for the type of the conditional expression just got more complex, which helps in many cases and doesn't really hurt in yours.

编译器不允许这样做,因为Integer.classFloat.class的类型是不可比的.没有类型T会使Class<T>成为Class<Integer>Class<Float>的超类型.

The compiler does not allow it because the types of Integer.class and Float.class are incomparable. There is no type T which would make Class<T> a supertype of both Class<Integer> and Class<Float>.

这篇关于为什么该程序可以用Java 7而不是Java 8编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆