Possible Duplicate:
Method Overloading for NULL parameter
The following code compiles and goes fine.
public class Main
{
public void temp(Object o)
{
System.out.println("The method with the receiving parameter of type Object has been invoked.");
}
public void temp(String s)
{
System.out.println("The method with the receiving parameter of type String has been invoked.");
}
public void temp(int i)
{
System.out.println("The method with the receiving parameter of type int has been invoked.");
}
public static void main(String[] args)
{
Main main=new Main();
main.temp(null);
}
}
In this code, the method to be invoked is the one that accepts the parameter of type String
The docs say.
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.
but I don't understand when one of the methods in the code that accepts the parameter of the primitive int
is modified to accept the parameter of the wrapper type Integer
such as,
public void temp(Integer i)
{
System.out.println("The method with the receiving parameter of type Integer has been invoked.");
}
a compile-time error is issued.
reference to temp is ambiguous, both method temp(java.lang.String) in methodoverloadingpkg.Main and method temp(java.lang.Integer) in methodoverloadingpkg.Main match
In this particular scenario, why is it legal to overload a method with a primitive data type which however doesn't appear to be the case with its corresponding wrapper type?
First to understand why
main.temp(null);
resolves totemp(String s)
and nottemp(Object o)
I point you at my old reply to Java method dispatch with null argument. Essentially, the literalnull
is of typenulltype
andObject
<String
<nulltype
. Sonull
is closer toString
then it is toObject
.Now,
null
is as close toString
as it is toInteger
, so when you addtest(Integer)
it becomes ambiguousIf you were asked what is more specialized "String" or "Object", what would you say? Evidently "String", right?
If you were asked: what is more specialized "String" or "Integer"? There is no answer, they are both orthogonal specializations of an object, how can you choose between them? Then you must be explicit regarding which one you want. For instance by casting your null reference:
When you use primitive types you do not have that problem because "null" is a reference type and cannot conflict with primitive types. But when you use reference types "null" could refer to either String or Integer (since null can be cast to any reference type).
See the answer in the other question that I posted in the comments above for further and deeper details and even a few quotes from the JLS.
Where you pass
null
as argument for an overloaded method, the method choosen is the method with the most specialized type, so in this case:String
is choosen rather than the most tolerant:Object
.Among
Object
/String
/int
the choice is clear for the compiler: you will get theString
's one cause anint
cannot benull
and so its corresponding method is not eligible to be called in this case.But if you change
int
forInteger
, compiler will be confuse because both methods takingString
is as accurate asInteger
's one (orthogonal in hierarchy).And the compiler can't (doesn't want? ^^) choose randomly.