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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With