Why does this program compile with Java 7 but not Java 8? [duplicate]

孤人 提交于 2019-12-12 10:57:02

问题


Consider this program:

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);
    }
}

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
$

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
$

And which is true:

  1. This is bug in Java 7 that got fixed in Java 8 (compiler was too permissive); or
  2. This is a new bug that was introduced in Java 8

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)


回答1:


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.

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>.



来源:https://stackoverflow.com/questions/32384531/why-does-this-program-compile-with-java-7-but-not-java-8

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!