I've come across a situation that is illustrated by this extremely oversimplified example:
static class ComparableContainer<T extends Comparable<? super T>> {
T comparableValue;
}
static void processComparableContainer(ComparableContainer<?> container) {
System.out.println(getComparableValue(container));
}
static <U extends Comparable<? super U>> U getComparableValue(ComparableContainer<U> container) {
return container.comparableValue;
}
The basic situation is that, given a class with a generic type parameter T extends Comparable<? super T>
, I need to pass an instance with unknown T
into a method that is parameterized with identical bounds. Interestingly enough, the version of Eclipse where I originally wrote the code compiles and executes it without any issues, but javac
reports the following error:
SimpleExample.java:7: error: method getComparableValue in class SimpleExample cannot be applied to given types;
System.out.println(getComparableValue(container));
^
required: ComparableContainer<U>
found: ComparableContainer<CAP#1>
reason: inference variable U has incompatible bounds
equality constraints: CAP#1
upper bounds: Comparable<? super U>
where U is a type-variable:
U extends Comparable<? super U> declared in method <U>getComparableValue(ComparableContainer<U>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Comparable<? super CAP#1> from capture of ?
1 error
From what I can tell, based on the answers to this and other questions, the Eclipse behavior is actually a bug, which has been fixed in Oxygen (my project is currently on Neon, which is why it still compiles in the version of Eclipse I am using). My question is, why does the Java compiler reject this method call? Under what circumstances could X extends Comparable<? super X>
and Y extends Comparable<? super Y>
be incompatible with one another? Is there a way I can get around this issue?