5

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)

Archie
  • 4,959
  • 1
  • 30
  • 36

1 Answers1

0

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

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436