Wildcards in generics behave differently in Java 7 and 8
I have the code compiled when it is compiled into Java 7 (eclipse compiler), but it fails when I set the project to Java 8:
package scratch; class Param<T extends Comparable<T>> { public Comparable<?> get() { return null; } } public class Condition<T extends Comparable<T>> { public static <T extends Comparable<T>> Condition<T> isInRange(T lower,T upper) { return null; } public void foo() { Comparable bound = null; // Line 15 Param<?> param = new Param<Double>(); Condition.isInRange(param.get(),bound); // Line 17 } }
In Java 7, I received the following warning:
>Line 15: comparable is the original type We should parameterize the reference to generic type Comparable > seventeenth lines: type safety: isInRange (Comparable, Comparable) of isInRange (T, T), which is not a general method of calling type.
When I add On line 15, the warning disappears, but I get an error on line 17:
Who knows what led to this intransigence?
PS: I added these ugly casts to compile code under two versions of Java:
Condition.isInRange((Comparable)param.get(),(Comparable) bound);
Solution
First of all, I'm not a generic expert, so my answer may not be correct I think the problem is how the isinrange method is defined
<T extends Comparable<T>>
This is a recursive definition and is not a problem in itself Look at courses like double and long I believe that because of how to resolve recursive definitions, the type of method (isinrange) must be a class that implements comparable, and it uses itself as a generic type of comparable; For example, class C implements comparable < C >