Compilers behave differently with a null parameter of a generic method

The problem is due to a JLS specification that mandates that otherwise uninferrable type arguments must be inferred as Object, even if it doesn’t satisfy the bounds (and would consequently trigger a compilation error).

The following is an excerpt from the “bug” report (which has been further annotated for clarity):

“Bug” ID 6299211 – method type variable: inference broken for null

This program does not compile:

public class Try {
    void m() {
        java.util.Collections.max(null);
    }
}

State: CLOSED, NOT A DEFECT.

Evaluation: THIS IS NOT A BUG. The inference algorithm cannot gather any information from the argument (null) and the method is not called in a place where there are any expectations on the returned value. In such cases the compiler must infer java.lang.Object for the type variable.


JLS 15.12.2.8 Inferring Unresolved Type Arguments

Any remaining type variables that have not yet been inferred are then inferred to have type Object


However, Object is not a subtype of Comparable<? super Object> and thus not within the bounds of the type variable in the declaration of Collections.max:

<T extendsObject & Comparable<? super T>> T max(Collection<? extends T>)


Further explorations

Using explicit type parameters “fixes” the problem:

HowBizarre.<Number,Integer>doIt(null); // compiles fine in javac

To show that this has less to do with a null argument and more to do with the absolute lack of information for type inferrence, you can try e.g. either of the following declarations:

<T,U extends Comparable<T>> void doIt()

<T extends Number,U extends T> void doIt()

In either case, an invocation doIt(); doesn’t compile in javac, as it must infer U to be Object as per 15.12.2.8, even if doing so would trigger a compilation error.


Note on Eclipse

While none of the snippets above compile in some version of javac, they all do in some version of Eclipse. This would suggest a bug on Eclipse’s part. It’s been known that there are disagreements between the different compilers.

Related questions

Leave a Comment