16

Possible Duplicate:
Method Overloading for NULL parameter

In the code below the output is

String

and if I remove the method with the parameter of type String then the output is

Object

I know how overloading of methods acts when the parameter types don't match exactly but I can not understand how null can be treated as an Object and/or a String parameter.

What is the explanation for this?

class C {

    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }

    public static void main(String[] args) {
        m1(null);
    }
}
Community
  • 1
  • 1
Sudeepta
  • 2,194
  • 4
  • 20
  • 24

5 Answers5

17

It always uses the most specific method according to the Java specs, section 15.12.2.5.

The intro is reasonably specific about it:

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.

The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.

Generally speaking, and at least for code readability, it's always best to try to be as explicit as possible. You could cast your null into the type that matches the signature you want to call. But that's definitely a questionable practice. It assumes everyone knows this rule and makes the code more difficult to read.

But it's a good academic question, so I +1 your question.

Community
  • 1
  • 1
mprivat
  • 21,582
  • 4
  • 54
  • 64
  • But how null match with the signature. It's neither a String nor an Object. – Sudeepta Jul 24 '12 at 17:08
  • 4
    A String or an Object can be represented as a null, right? Therefore a null can represent either type, therefore both signatures match. But since String extends Object, String is more specific and that method is given preference when the call is ambiguous. – mprivat Jul 24 '12 at 17:47
8

When multiple overloads match a signature, Java picks the most specific method from among them.

The value of null matches both Object and String, but String is a subclass of Object, so String is picked. If you add another overload with a sibling of String in the class hierarchy, you'd get a compile error.\

// DOES NOT COMPILE
class C {
    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }
    static void m1(Integer x) {
        System.out.print("Integer");
    }
    public static void main(String[] args) {
        m1(null);
    }
}

Here is a link to a post that discusses your code example at some length.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
5

If you need to force the call of a aprticular overloaded method when passing null as parameter, you have to cast it, like this:

m1((String)null);

By doing this, you make sure you're calling the correct overloaded version of the method.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
2

You have to set the type of null to tell Java what function you want to call.

So you do: m1((Object) null); to call the implementation with the Object parameter and you do m1((String) null); to call the other one.

Nitram
  • 6,486
  • 2
  • 21
  • 32
1

1. As String is also an object the JVM got confused to call which method at runtime.

2. If you want to specify which method to call at runtime, you can do this by explicit casting

eg:

m1((String)null);
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • That's not the reason JVM got confused. It will always find the most specific method. The reason it gets confused is becaus null is neither a String or an Object. – David Feb 08 '15 at 11:49