18.5.2 "the resulting instantiations are not considered part of B1."

Stephan Herrmann stephan.herrmann at berlin.de
Thu Nov 21 07:38:50 PST 2013

I'm looking at this example:

     public static <T> void myMethod(final List<? extends File> fileList) {
         Collections.sort(fileList, new Comparator<File>(){
             public int compare(File f1, File f2) { return 0; }

Check for applicability creates these type bounds
(where T#0 stands for an inference variable for T):
     T#0 = capture#1-of ? extends File
     T#0 <: File
     T#0 <: java.lang.Object
We have a solution, so we proceed to inferring the invocation type.

Now 18.5.2 says I should use the above bounds (B1) but "the resulting
instantiations are not considered part of B1."

I see two possible interpretations of this, neither of which produces
the desired result.

(1) I could drop the first bound entirely (because this effectively
instantiates T#0. Result: T#0 will be inferred to File with is the
wrong result, sort(List<File>,Comparator<File>) does not accept
the argument of type List<? extends File>.

(2) I could keep all the bounds but forget the fact that one of
them actually comprises an instantiation. Now resolution will
- (first attempt) add T#0 = File, which is in conflict with the
   existing bound
- (second attempt) add T#0 = Z, where Z is a fresh type variable
   Also this fails the inference because of this constraint:
      Z = capture#1-of ? extends File
Ergo, this variant produces no solution.

Only by ignoring that sentence of the spec (i.e., keeping the
instantiation from B1) can I make inference succeed.

All compilers accept the example without warning/error,
but I don't see how the inference can make this work.

what am I missing?

More information about the lambda-spec-experts mailing list