-
-
Save odrotbohm/c644327bb89191f2b52e298427ebf201 to your computer and use it in GitHub Desktop.
public class AmbiguitySample { | |
/** | |
* This compiles when using a JDK 8 with target JDK 6 but fails when the target is JDK 8. | |
*/ | |
public static void main(String[] args) { | |
CriteriaBuilder builder; | |
Expression<Object> objectExpression; | |
Expression<Collection<Object>> collectionOfObjectExpression; | |
// Compiler error: AmbiguitySample.java:[35,24] reference to isNotMember is ambiguous | |
// [ERROR] both method | |
// <E,C>isNotMember(javax.persistence.criteria.Expression<E>,javax.persistence.criteria.Expression<C>) in | |
// javax.persistence.criteria.CriteriaBuilder and method | |
// <E,C>isNotMember(E,javax.persistence.criteria.Expression<C>) in javax.persistence.criteria.CriteriaBuilder match | |
builder.isNotMember(objectExpression, collectionOfObjectExpression); | |
// ^^^^^^^^^^^ | |
} | |
} |
This problem kept me interested a while... It seems like a problem in "target-type inference" from java8. See: http://stackoverflow.com/questions/32294140/java-8-reference-to-method-is-ambiguous . Java8 is using target-type inference to infer the type of E, but there must be an exception when using <Object> as generic type, because if you use something different/more specific, it will work. Here is another working alternative:
void test(CriteriaBuilder builder,
Expression<? extends Object> objectExpression,
Expression<? extends Collection<Object>> collectionOfObjectExpression) {
builder.isNotMember(objectExpression, collectionOfObjectExpression);
}
You can also trick the compiler into the correct behavior with this piece of code:
<T> void test(CriteriaBuilder builder, Expression<T> objectExpression,
Expression<Collection<T>> collectionOfObjectExpression) {
builder.isNotMember(objectExpression, collectionOfObjectExpression);
}
Sorry, I've been in a hurry and thought I'd just oversee something. I've no prepared a reproducing example here. Run mvn clean compile
see it fail. Change the java.version
property to 1.6
see it compile.
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)
@otrosien — once again, you made my day. Thanks for that!
Not that I have any chance of answering this but it would be easier to play around with if it contained all required source code.