6

Possible Duplicate:
Overloaded method selection based on the parameter’s real type
How is an overloaded method choosen when a parameter is the literal null value?

When I execute the code below, I get the following output:

Method with String argument Called ..."

Why?

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test(null);
    }
}
5
  • So you have an overloaded method 'test' and you called it with a string, but you want to know why the object one did not get called? Commented Oct 30, 2012 at 5:33
  • It's just because the String class is a specialized form of the Object class (owing to the fact that the String class has every feature of the Object class in addition to its own) which is chosen by the compiler as specified by the JLS (the most specific method is chosen which is in your case, the one that accepts a parameter of type String). Commented Oct 30, 2012 at 5:41
  • 1
    These are also the similar threads you may want to refer to How is an overloaded method choosen when a parameter is the literal null value?, Using null to overload methods in Java Commented Oct 30, 2012 at 6:05
  • Theoretically null reference is not of any type, then why JVM chooses String not Object. I think as Object is base for every classes in Java then It should invoke method with Object argument. Commented Oct 30, 2012 at 6:06
  • 1
    @Alpesh Gediya - That's because null in your case can be resolved to both String as well as to Object. Doesn't it? (both Object and String can be null) Therefore, the most specific method is chosen by the compiler as specified in the Java language specification (JSL) and the most specific method in your case is the one that accepts a String parameter. Commented Oct 30, 2012 at 6:08

5 Answers 5

3

The null in the call matches both the test() signatures. You have to cast the null to ensure it calls one or the other.

Sign up to request clarification or add additional context in comments.

2 Comments

Java will also try to use the most specific version of a method that is available. This is why it choses String rather than Object.
I'm used to Eclipse telling me to fix it before I get the chance to wrote this sort of code too.
3

A similar example is from Java Puzzles if I recall correctly.

null can be of String type or Object type. But the JVM will always choose a more accurate method.

In this case, String is more accurate then Object. (a String is an Object, but an Object might not be a String).

It is not a good habit to write code like this. Try to cast parameters to match your desired method, like

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test((Object)null);
    }
}

Comments

2

I tried this:

Test2.class

public class Test2{}

Test3.class

public class Test3 extends Test2{

}

Test.class

public class Test{

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

public static void print(Test2 obj){
    System.out.println("test 2");
}

public static void print(Test3 obj){
    System.out.println("Test 3");
}


public static void main(String[]args){
    Test.print(null);
}

}

it printed out Test 3

Just like in your scenario, this means that if a method is overloaded (and when null is passed), it recognizes the method which has the child-most parameter.

Object->Test->Test2

or in your case:

Object->String

Comments

2

Java tries to find the most specific method possible to call. String is a subclass of object, so Java will defer to the String method whenever it can. null is a perfectly acceptable value for either an Object or a String, but since a String is more specific than an Object, Java defers to the String method because it is more precise.

Comments

1

null is could be both a String and/or an Object but because String inherits from Object, it will try to use the signature that is more precise. You can cast null to choose which method to execute:

public static void main(String[] args) {
    Test.test((Object) null); // treats as Object
    Test.test((String) null); // treats as String
    Test.test(null);          // treats as String
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.