27

Just out of curiosity I tried this example.

public class Class1 {

    public void method(Object obj){
        System.out.println("Object");
    }

    public void method(String str){
        System.out.println("String");
    }

    public static void main(String... arg){
        new Class1().method(null);
    }

}

The output being "String". I want to know on what basis the JVM decides to invoke method taking String as argument and not Object.

Aditya
  • 1,033
  • 3
  • 11
  • 24
  • Isn't this a compile error? Something about ambiguous parameters? – Thilo Jul 16 '13 at 06:54
  • Apparently not. I wish it was. – Thilo Jul 16 '13 at 06:55
  • 1
    Nothing ambiguous about this, @Thilo. It would be ambiguous if the first method accepted `Integer` and the second `String`, since then neither of them would be "more specific" than the other. – Joni Jul 17 '13 at 13:59
  • @Joni: Yes, not ambiguous if you know all the exact rules of the spec in detail. But a bit unclear if you don't. It cannot be denied that method selection rules have become quite complex with the introductiong of varargs, generics and autoboxing (of course this particular case has been there since Java 1). I find it weird that Java (which otherwise often leans towards verbose and explicit) is so "flexible" here. Makes for good quiz questions, but not really helpful in everyday's programmer life. – Thilo Jul 17 '13 at 23:06
  • If you overload with Integer parameter, this will result in compile error. Between String and Object, Object is superior and String is more specific so JVM will choose String however between String and Integer, there is no comparison and hence JVM will get confuse and throw ambiguous error at compile time. – Gautam Tadigoppula Jun 14 '20 at 19:12

7 Answers7

20

Whenever more than one overloaded methods can be applied to the argument list, the most specific method is used.

In this case either of the methods can be called when passing null, since the "null type" is assignable to both Object and to String. The method that takes String is more specific so it will be picked.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • how can i call the least specific method ?? – Sagar Nayak Jun 30 '17 at 10:07
  • Use type casts. For example, `method((Object) null)` – Joni Jun 30 '17 at 11:00
  • i use that for now. but lets say i am using this method as a exposed method of a library. so i dont want user to do all this type casting and all. user will just pass the value and i have to programmatically redirect the control to appropriate method. is there any other way ? @joni – Sagar Nayak Jun 30 '17 at 11:31
  • You can use the reflection api to list the methods of a class or object, and then call the one you think is most appropriate. Sounds like this should be an independent question on Stackoverflow – Joni Jun 30 '17 at 11:45
  • @Joni method((Object) null) still called the string parameterized method – Coder17 Feb 04 '22 at 10:10
  • Nice answer, I was searching for C# and just to leave here at it's the same there. – gneric Jun 28 '23 at 06:53
11

Whenever there's Method Overloading, the JVM will search for the method from the most specific type to least specific type

Edd
  • 3,724
  • 3
  • 26
  • 33
RaceBase
  • 18,428
  • 47
  • 141
  • 202
  • 2
    I suggest editing your quote from `most closest` to `most specific type` would be more appropriate in terms of programming lang. – exexzian Jul 16 '13 at 06:55
  • Made correction. Thanks for that. I meant the same, however your words make more sense. – RaceBase Jul 16 '13 at 06:56
  • 5
    It's the compiler that decides which method should be called, not the JVM. – Joni Jul 16 '13 at 07:59
7

See the JLS specification

15.12.2.5. Choosing the Most Specific Method

It is one of the puzzle of Java Puzzlers by Joshua Bloch - Puzzle 46: Case of the Confusing Constructor

Edd
  • 3,724
  • 3
  • 26
  • 33
veritas
  • 2,444
  • 1
  • 21
  • 30
2

Java Compiler chooses the most specific method.

String is a more specific type compared to the Object.

Code Enthusiastic
  • 2,827
  • 5
  • 25
  • 39
0

Becaue you are passing null in calling method and you defined void method(String str) And String always initlize with null. it will find that matching parametrized method. Thats y u got "str" on console.

0

When you are doing method overloading, jvm tries to the next in hierarchy. For e.g. if you overload methods with long and int, but invoke method by passing byte, it will first go to int as it is next in hierarchy to byte.

Sandiip Patil
  • 456
  • 1
  • 4
  • 21
0

It's because of method Overloading

The most specific method is chosen at compile time.

As 'java.lang.String' is a more specific type than 'java.lang.Object'. In your case it returns String.

Vimal Panchal
  • 301
  • 1
  • 5
  • 15