18
package org.study.algos;
public class Study {

    public static void main(String[] args) {
       A a = new A();
       a.m1(null);
    }
 }
 class A {
    public void m1(String s) {
       System.out.println("String");
        System.out.println(s);
    }
    public void m1(Object obj) {
       System.out.println("Object");
       System.out.println(obj);
    }
}

Here, the output is

String null

Why does the JVM resolve the method to one with a String argument?

Thanks in advance J

Termininja
  • 6,620
  • 12
  • 48
  • 49
Jijoy
  • 12,386
  • 14
  • 41
  • 48

5 Answers5

16

It's a fairly elaborate algorithm, detailed in JLS 15.12. But the part that is relevant here is 15.12.2, which says "the most specific one is chosen." Both the Object and String overloads are "accessible and applicable" (the String is applicable because a null literal is a reference of all types), and the String is more specific.

EDIT: Corrected section, per Syntactic.

Tmdean
  • 9,108
  • 43
  • 51
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • 2
    I think you want 15.12.2. 15.11.2 is about accessing superclass members with the super keyword. – Syntactic Apr 09 '10 at 14:55
  • how can i call the least specific method ?? if i have foo(Object o); and foo(String s);. and i want to call foo(Object o). what do i do ? – Sagar Nayak Jun 30 '17 at 10:24
10

These methods are "overloaded", not "ambiguous".

According to the Java Language Specification:

When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2).

And §15.12.2 says:

There may be more than one such method, in which case the most specific one is chosen.

String is more specific than Object, so while null is compatible with both, the method with the String parameter is chosen (there are much more complex rules that apply when the parameter types are part of a class or interface hierarchy).

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
2

null value can be set to reference of any type. All overloaded methods you have are in one inheritance hierarchy Object <- String, the least general one is being choosen. But if you had two overloaded methods that are not in the same hierarchy, then you'd get compilation error about ambigous methods.

Mirek Pluta
  • 7,883
  • 1
  • 32
  • 23
0

A String is an Object, an Object is not a String, thus the first overload is more specific than the second. See JLS 15.12.2, as Syntactic mentioned.

Dimitris Andreou
  • 8,806
  • 2
  • 33
  • 36
0

I asked a similar question. Jon Skeet wrote a big answer.

The link to my question: Which overload will get selected for null in Java?

Community
  • 1
  • 1
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287