Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method overload selection with null

Given this code:

class Overloading
extends Object
{

static public void target(Object val, String chk) { System.out.println("Object["+val+"] :: Should be "+chk); }
static public void target(String val, String chk) { System.out.println("String["+val+"] :: Should be "+chk); }

static public void main(String[] args) {
    Object                              obj=null;

    target(null        ,"Object");
    target((Object)null,"Object");
    target(obj         ,"Object");
    }
}

the output is (unexpectedly) as follows:

String[null] :: Should be Object
Object[null] :: Should be Object
Object[null] :: Should be Object

The problem is with the first line, which I expect to be the same as the other two. Furthermore, I would swear that until recently the compiler would give me an ambiguous invocation warning for the plain null call. However compiling and testing with Java 5 and 6 yields the same results.

This is a significant issue for me since I have a lot of code which uses this pattern of using an overloaded "default" parameter of different types to select a return type and infer required conversion/parsing. Can anyone explain what is going on here?

like image 667
Lawrence Dol Avatar asked Jan 19 '23 21:01

Lawrence Dol


1 Answers

Java has always worked the same way: the "most specific" applicable overload is always chosen. Since String is a subclass of Object, it is "more specific", and the String overload is chosen. If the overloads were for, say String and Integer, and you tried to pass null, then you would indeed get a compile-time ambiguity error, since they are both at the same level of the same inheritance hierarchy.

like image 161
Ernest Friedman-Hill Avatar answered Jan 30 '23 05:01

Ernest Friedman-Hill