Skip to content

Instantly share code, notes, and snippets.

@aeisenberg
Created November 16, 2016 02:50
Show Gist options
  • Save aeisenberg/de558a35d09de0184be2707cfe42c921 to your computer and use it in GitHub Desktop.
Save aeisenberg/de558a35d09de0184be2707cfe42c921 to your computer and use it in GitHub Desktop.
import java.util.Collection;
public class Ambiguity {
public void foo(CriteriaBuilder builder) {
// change Object -> Number (or any other type) and it compiles
Expression<Object> objectExpression = null;
Expression<Collection<Object>> collectionOfObjectExpression = null;
builder.isNotMember(objectExpression, collectionOfObjectExpression);
}
}
class Expression<T> { }
class CriteriaBuilder {
public <E,C extends Collection<E>> void isNotMember(E elem, Expression<C> collection) {}
public <E,C extends Collection<E>> void isNotMember(Expression<E> elem, Expression<C> collection) {}
}
@odrotbohm
Copy link

It still doesn't entirely make sense to me:

  1. To consider the first method a match, E has to be bound to Expression<Object>. That'd mean the second parameter is expected to be an Expression<Collection<Expression<Object>>>. But we hand in a Expression<Collection<Object>> so that shouldn't match, should it?
  2. There is no Java 6 involved at all. It also compiles if you use a JDK 8 compiler but set the source and target level to 1.6.
  3. My actual question is: if I have the two variables of type Expression<Object> and Expression<Collection<Object>>, how do I tell the compiler I want to bind to the second method? There doesn't seem to be any way (through type hints, casts or the like) to get this to work.

@odrotbohm
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment