java - Why does the compiler not deduce captures relationships in generics? -


this question has answer here:

imagine interface this

public interface messageparameter<t> {    public list<t> unmarshal(byte[] array);   public int getlength(list<t> values);  } 

and consumer of interface

public class genericuser {    list<messageparameter<?>> payload = new arraylist<>();    public void run() {      byte[] bytearray = new byte[] { 1, 2 };       (messageparameter<?> element : payload) {         element.getlength(element.unmarshal(bytearray)); //compiler error      }   } } 

the compiler gives error

 method getlength(list<capture#1-of ?>) in type messageparameter<capture#1-of ?> not applicable arguments (list<capture#2-of ?>) 

clearly since using element in both method calls, type of both same , should allowed. way ask same question, why compiler creating capture#2?? why can't deduce logically both same capture?

am missing something? there counter-example code throw runtime exception??

my main question not how fix code (although interesting well, current solution use object instead of ?), what logical reason error? looks me shortcoming on implementation of compiler more logical limitation

the answer compiler not smart accept runtime type corresponding ? same because not care one-line expression involves same element:

element.getlength(element.unmarshal(bytearray)); 

is semantically similar to:

list<?> unmarshalledlist = element.unmarshal(bytearray); element.getlength(unmarshalledlist); 

in case, not obvious list unmarshalledlist surely have have same "any-type" 1 expected getlength(). above 2 separate statements (even though they're contiguous). imagine they're not contiguous. may have like:

messageparameter<?> otherelement = getotherelement(); (messageparameter<?> element : payload) {     list<?> unmarshalledlist = element.unmarshal(bytearray);     // unmarshalledlist can re-assigned parameterized type     unmarshalledlist = otherelement.unmarshal(bytearray);     element.getlength(unmarshalledlist);  // error } 

in other words, compiler cannot assume variable unmarshalledlist retain same ? type element when program reaches statement invoking getlength on same element. can re-assigned different parameterized type in between.


Comments