9
public class Test1  {

    public static void main(String[] args)   {
        Test1 test1 = new Test1();
        test1.testMethod(null);
    }

    public void testMethod(String s){
        System.out.println("Inside String Method");     
    }

    public void testMethod(Object o){
        System.out.println("Inside Object Method"); 
    }
}

When I try to run the given code, I get the following output:

Inside String Method

Can anyone explain why the method with the String type parameter is getting called?

hopper
  • 13,060
  • 7
  • 49
  • 53
Java_Sape
  • 151
  • 3
  • 1
    +1 It looked like super easy question, but using null... That's interesting indeed... – Eel Lee Oct 08 '13 at 09:21
  • 2
    possible duplicate of [Strange Java null behavior in Method Overloading](http://stackoverflow.com/questions/14789478/strange-java-null-behavior-in-method-overloading) – Rohit Jain Oct 08 '13 at 09:27
  • @RohitJain that question is already a duplicate of [this](http://stackoverflow.com/questions/1545501/which-overload-will-get-selected-for-null-in-java) – mariomario Oct 08 '13 at 11:59

2 Answers2

19

most specific method argument is chosen for overloaded methods

In this case, String is subclass of Object. Hence String becomes more specific than Object. Hence Inside String method is printed.

Directly from JLS-15.12.2.5

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

As BMT and LastFreeNickName have correctly suggested, (Object)null will cause overloaded method with Object type method to be called.

Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56
  • 3
    But for null, String and Object both are at the Same level , then how String can be more specific ? – Java_Sape Oct 08 '13 at 09:23
  • 5
    Fully correct! You can try and pass (Object)null as parameter and it will choose the other method. – LastFreeNickname Oct 08 '13 at 09:24
  • 3
    Whenever it encounters a string literal in your code, the compiler creates a `String object` with its value—in this case, *Null*. – bNd Oct 08 '13 at 09:25
  • @BMT Eh? `null` isn't the value of any string literal (although `"null"` might be), and there is no string literal in the OP's code anyway. What are you talking about? – user207421 Oct 09 '13 at 01:24
0

Adding on to an existing reply, I'm not sure if this is because of a newer Java version since the question, but when I tried to compile the code with a method taking an Integer as a parameter instead of an Object, the code still did compile. However, the call with null as the parameter still invoked the String parameter method at run-time.

For example,

public void testMethod(int i){
    System.out.println("Inside int Method");     
}

public void testMethod(String s){
    System.out.println("Inside String Method");     
}

will still give the output:

Inside String Method

when called as:

test1.testMethod(null);

The main reason for this is because String does accept null as a value and int doesn't. So null is classified as a String Object.

Coming back to the question asked, The type Object is encounter only when a new object is created. This is done by either type casting null as an Object by

test1.testMethod((Object) null);

or using any type of object for a primitive data type such as

test1.testMethod((Integer) null);
    or
test1.testMethod((Boolean) null);

or by simply creating a new object by

test1.testMethod(new  Test1());

It should be noted that

test1.testMethod((String) null);

will again invoke the String method as this would create an object of type String.

Also,

test1.testMethod((int) null);
    and
test1.testMethod((boolean) null);

will give a compile time error since boolean and int do not accept null as a valid value and as int!=Integer and boolean!=Boolean. Integer and Boolean type cast to Objects of type int and boolean.

Laurel
  • 5,965
  • 14
  • 31
  • 57