0

I have the two following overloaded methods:

public static void test(Integer n) {
    System.out.println("Integer");
}

public static void test(Number n) {
    System.out.println("Number");
}

when I invoke the test method with null, something like that:

public static void main(String[] args) throws Exception {
    test(null);
}

I receive:

Integer

Could you please explain why do I receive the Integer and not a compilation error because it is really not obvious with null parameter what test method should be executed?

alexanoid
  • 24,051
  • 54
  • 210
  • 410
  • IIRC this is covered in the JLS, 15.2.mumbleish – Dave Newton Jun 27 '18 at 15:06
  • 1
    It chooses the method with the most specific type. In this case `Integer`, because it's a subtype of `Number`. If you add another method that takes a `Double`, you will get a compile error because the call is ambigious. – marstran Jun 27 '18 at 15:07
  • Because for overloading must be choosen the most specific method (https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5), and `Integer` is more specific, that `Number` – Michel_T. Jun 27 '18 at 15:08
  • The best thing to do, is completely avoid doing things like this. Check for nulls on input, use different method signatures or inheritance so it is clear what you want to call. – ergonaut Jun 27 '18 at 15:28

1 Answers1

2

The <null> type is an acceptable value for both Integer and Number so both are possible overloads.

Java then chooses the most specific overload.

Since Integer is a subtype of Number, it is more specific.

See 15.12.2. Compile-Time Step 2: Determine Method Signature:

If several applicable methods have been identified during one of the three phases of applicability testing, then the most specific one is chosen, as specified in section §15.12.2.5.

And the relative specificity of Integer and Number falls out of this rather opaque spec language in §15.12.2.5:

  • m2 is not generic, and m1 and m2 are applicable by strict or loose invocation, and where m1 has formal parameter types S1, ..., Sn and m2 has formal parameter types T1, ..., Tn, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ n, n = k).
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245