This question already has answers here:
How to do method overloading for null argument?
(7 answers)
Closed 5 years ago.
public class CompilerConfuse {
public static void main(String[] args) {
A a =new A();
a.method(null); // error line
}
}
class A
{
public void method(Integer a)
{
System.out.println("In Integer argument method" + a);
}
public void method(Object a)
{
System.out.println("In Object argument method" + a);
}
public void method(String a)
{
System.out.println("In String argument method " + a);
}
}
In Integer and String overload method,Compiler could not able to decide which one to call.Why this happening?
If we remove either of String or Integer overload method it is not giving error when passing null.
The compiler selects the method the most specific according to the type of the passed argument(s).
In your case, String and Integer are more specific than Object but both are also as much specific, so the compiler doesn't chose between and emits a compilation error.
You can refer to 15.12.2.5. Choosing the Most Specific Method :
It is possible that no method is the most specific, because there are
two or more methods that are maximally specific. In this case:
If all the maximally specific methods have override-equivalent
signatures (ยง8.4.2), then:
...
Otherwise, the method invocation is ambiguous, and a compile-time
error occurs.
Related
This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 6 years ago.
Which overloaded method will be called for the below method and why?
I executed this code and it calls the overloaded method with List but why does it happen?
public class AmbigiousOverload {
public static void add(Object o) {
System.out.println("Overloaded method with Object.");
}
public static void add(List l) {
System.out.println("Overloaded method with List.");
}
public static void main(String[] args) {
add(null);
}
}
Output: Overloaded method with List.
The List overload is called because the List overload is the most specific matching overload, as all List implementations are subclasses of Object.
From JLS Sec 15.12.2.5:
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 error.
Since any parameter you can pass to add(List) can also be passed to add(Object), add(List) is more specific. As such, given that null can be passed to both, the more specific method is the one chosen.
Note that it wouldn't compile if you had an add(String) overload, since List and String are "equally" specific. (Or any other class: it doesn't have to be String).
This question already has answers here:
Overloaded method selection based on the parameter's real type
(7 answers)
Closed 6 years ago.
Why doAction(A a) will be selected in this situation?
Can you advice some articles to read about method selection depending on argument type?
class A { }
class B extends A { }
class D {
void start(A a){
doAction(a);
}
void doAction(A a) {
System.out.println("A action");
}
void doAction(B b) {
System.out.println("B action");
}
}
public class Test {
public static void main(String[] args) {
new D().start(new B());
}
}
Why doAction(A) will be selected in this situation?
Because it's the only applicable method. Overload resolution is performed at compile-time, based on the compile-time type of the arguments.
The doAction(B) method isn't applicable, because there's no implicit conversion from A (the type of your argument) to B (the type of the parameter). You could cast the value to B like this:
doAction((B) a);
At that point both methods would be applicable, but overload resolution would pick doAction(B b) as being more specific than doAction(A a). Of course, it will also fail if you pass in a reference which isn't to an instance of B.
You should read JLS 15.12.2 for the precise details of overload resolution.
This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 7 years ago.
I have the following structure of my class:
void add(String s){
System.out.println("string");
}
void add(Object s){
System.out.println("object");
}
public static void main(String[] args) {
new MyClazz().add(null);
}
O/P : string
Why object is not called?
String is more specific than Object. Therefore void add(String s) is preferred over void add(Object s).
15.12.2. Compile-Time Step 2: Determine Method Signature
The second step searches the type determined in the previous step for
member methods. This step uses the name of the method and the argument
expressions to locate methods that are both accessible and applicable,
that is, declarations that can be correctly invoked on the given
arguments.
There may be more than one such method, in which case the most
specific one is chosen. The descriptor (signature plus return type) of
the most specific method is the one used at run time to perform the
method dispatch.
This question already has answers here:
Method overloading and choosing the most specific type
(9 answers)
Closed 8 years ago.
class Test {
public Test(Object obj) {
System.out.println("Object");
}
public Test(String s) {
System.out.println("String");
}
public static void main(String[] args) {
new Test(null); //prints String. Why not Object?
}
}
If I add another constructor with argument of type Integer ,or, for that matter any other type, calling new Test(null); results in compilation error - The constructor Test(Object) is ambiguous. Why no error is generated for the above example? On executing it, constructor with argument String is called. Why constructor with argument type Object is not called? How this ambiguity is resolved?
//prints String. Why not Object?
Because compiler choose most specific type.
If I add another constructor with argument of type Integer ,or, for
that matter any other type, calling new Test(null); results in
compilation error - The constructor Test(Object) is ambiguous.
Now String and Integer are in the same level in the object hierarchy, So, compiler can't choose one out of those two
Because it is determined by the most specific type of the parameter.
Since String is subclass of Object, and null is subtype of anything, then the second constructor is called, because String is more specific than Object.
Compiler is designed to pick up the overloaded method that very closely matches the Value sent in parameter.
This question already has answers here:
Java method dispatch with null argument
(4 answers)
Understanding which constructor is chosen and why
(4 answers)
Closed 9 years ago.
When I run this code it prints String. My question is why there is no compile time error?
Default value of Object and as well as String is null. Then why not compiler says Reference to method1 is ambiguous.
public class Test11
{
public static void method1(Object obj) {
System.out.println("Object");
}
public static void method1(String str) {
System.out.println("String");
}
public static void main(String[] arr ) {
method1(null);
}
}
From this answer:
There, you will notice that this is a compile-time task. The JLS says in subsection 15.12.2:
This step uses the name of the method and the types of the argument expressions to locate methods that are both accessible and applicable There may be more than one such method, in which case the most specific one is chosen.
The compiler will look at all the possible overloads of the method that could match the parameters you pass. If one of them is more specific than all the others then it will be chosen, it's only considered ambiguous if there is no single most specific overload.
In your example there are two possible overloads, method1(Object) and method1(String). Since String is more specific than Object there's no ambiguity, and the String option will be chosen. If there were a third overload such as method1(Integer) then there is no longer a single most specific choice for the call method1(null), and the compiler would generate an error.
Well in one sentence
In case of Overloaded methods compiler chooses the method with most
specific type, as String is the most specific type of Object compiler
will invoke the method which takes string as an argument
public class Test11
{
public static void method1(String str)//here str is the object of string
{
System.out.println("String");
}
public static void method1(Object obj)//here this is a common object not specified
{
System.out.println("Object");
}
public static void main(String[] arr )
{
Test11 t=new Test11();
String null1=new String();
method1(null1);
method1(t);
}
}
output is :
String
Object
//null1- is a string object if u pass this it will call method1(String str) only because u pass string object
//t-is general object if u pass this it will call method1(Object obj)only because u pass class objct so it will pass object as parameter