0

Why is the method with a parameter of type Object[] called rather than the method with a parameter of type Object when null is passed as the argument?

class Demo {
    void show(Object arr[]) {
        System.out.println("khawar");
    }

    public void show(Object o) {
        System.out.println("aleem");
    }

    public static void main(String[] args) {
        Demo ss=new Demo();
        ss.show(null);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
khawar
  • 11
  • 1
  • possible duplicate of [Why is it not allowed in Java to overload Foo(Object...) with Foo(Object\[\])?](http://stackoverflow.com/questions/8838339/why-is-it-not-allowed-in-java-to-overload-fooobject-with-fooobject) – Eng.Fouad Oct 29 '13 at 07:18
  • because it is closer in hierarchy – jmj Oct 29 '13 at 07:19
  • As an aside, `void show(Object arr[])` would be more idiomatically written as `void show(Object[] arr)` - keep the array part along with the rest of the type information. – Jon Skeet Oct 29 '13 at 07:23
  • I've edited the question significantly to make it a lot more readable. Please let me know if you object to any of the editing. – Jon Skeet Oct 29 '13 at 07:25

3 Answers3

4

Firstly, it's important to note that the null value is convertible to both Object and Object[], so both methods are applicable. Then it's just a matter of overload resolution. That's described in section 15.12 of the JLS, and section 15.12.2.5 in particular talks about finding "the most specific method", which includes:

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.

That's the case here: any invocation of show(Object[]) can be passed to show(Object) without a compile-time type error, therefore show(Object[]) is more specific than show(Object), so overload resolution picks show(Object[]) to invoke.

To invoke show(Object) you just have to cast the null to Object, to stop the show(Object[]) method from being applicable:

ss.show((Object) null);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

You'll have to go through the JLS to find the exact explanation, but basically the reason is, that the most specific method signature is chosen, and "null" acts as a more specific match to subclasses than superclasses.

// Where Subclass extends Middleclass extends Superclass
public void method(Superclass c) {}
public void method(Middleclass m) {}
public void method(Subclass s) {}

In the above case, a call to method(null) would call method(Subclass s).

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0

The most specific signature will be chosen when multiple candidates are matched. Object[] is an Object, therefore it is more specific where Object is more generic.

For instance, if you added show(Integer[]) then this would be the most specific candidate, and will be chosen over show(Object[]). If you added both show(Integer[]) and show(String[]) then you will get a compile time error specifying show(Object) is ambiguous, because both of the new added methods are candidates of equal specificity towards the call you are trying to make.

If you wanted to force call show(Object) instead, then you could write: show((Object)null);

Ben Barkay
  • 5,473
  • 2
  • 20
  • 29