Imagine an interface like this
public interface MessageParameter<T> {
public List<T> unmarshal(byte[] array);
public int getLength(List<T> values);
}
and a consumer of that interface
public class GenericUser {
List<MessageParameter<?>> payload = new ArrayList<>();
public void run() {
byte[] byteArray = new byte[] { 1, 2 };
for (MessageParameter<?> element : payload) {
element.getLength(element.unmarshal(byteArray)); //compiler error
}
}
}
The compiler gives an error
The method getLength(List<capture#1-of ?>) in the type MessageParameter<capture#1-of ?> is not applicable for the arguments (List<capture#2-of ?>)
Clearly since I am using element
in both method calls, the type of both is the same and it should be allowed. Another way to ask the same question, why is the compiler creating capture#2
?? why can't it deduce that they are logically both the same capture
?
Am I missing something? is there a counter-example where this code would throw a runtime exception??
My main question is not how to fix the code (although that would be interesting as well, my current solution is to use Object
instead of ?
), but what is the logical reason for this error? It looks to me like a shortcoming on the implementation of the compiler more than a logical limitation