Confusion about method overloading [duplicate] - java

This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 8 years ago.
I tried the following code, but don't understand the output:
Class A{
public void print(Object o){
System.out.println("Object");
}
public void print(String o){
System.out.println("String");
}
public static void main(String arr[]){
A obj = new A();
obj.print(null);
}
}
Output: String
Why??
Thanks for your attention!

The method with the more specific argument type is chosen. String is more specific than Object.
Note that if you had another print method with, say, an Integer parameter, you would get a compilation error, since in that case the compiler would have no rule to decide whether to call print(String) or print(Integer). The reason it works when you have print(String) and print(Object) is that String is a sub-class of Object, and therefore print(String) is preferred.

If there's method overloading, the compiler search for the method from the most specific type to least specific type
From JLS specification
15.12.2.5. Choosing the Most Specific Method
So String is a more specific type compared to the Object.

The least generic method among the matching methods will be selected by the compiler.
i.e, the compiler will first find out that both String and Object can be null. Then it selects the one which is at a lower level in the class hierarchy. (Object is at a higher level than String)

Related

Conflict on Overloading [duplicate]

This question already has answers here:
JAVA Object/String method overload [duplicate]
(7 answers)
Closed 8 years ago.
This question is bothering me for a while.Please help
Suppose there are two methods
public void add(Object obj){
/* some logic*/
}
public void add(String str){
/*Some logic*/
}
so when i call add(null) which method will get executed and why?
thanks
In this case the String argument version wins, because String is a more specific type as every class is a subclass of Object (except itself).
Anyway, you'll still be able to call the Object argument version by casting.
e.g.
app.add((Object) null);
If there're more than one potential match, such as having a version of add(Integer i) version available, it's an error, and won't compile.
It will call method with String argument...
classes in Java are direct or indirect subclasses of Object. So String is a subtype of Object, the method overloaded to accept a String is more specific than the method overloaded to accept an Object. A String can be converted (upcast) to Object, but an Object cannot be converted (downcast or upcast) to String, so the method taking the String argument is more specific. Therefore, print(String s) will be invoked by the call print(null).

Which method will get invoked during overloading when null is passed [duplicate]

This question already has answers here:
Which overload will get selected for null in Java?
(3 answers)
Strange Java null behavior in Method Overloading [duplicate]
(4 answers)
Closed 9 years ago.
In the following program:
public class PolyEx1 {
public static void main(String[] args) {
A refA = new A();
refA.method1(null);
}
}
class A {
public void method1(Object o) {
System.out.println("o");
}
public void method1(String str) {
System.out.println("str");
}
}
The output is "str", can someone explain me why str was printed? I am not able to understand this.
As explained by Rohit here,
That is because String class extends from Object and hence is more
specific to Object. So, compiler decides to invoke that method.
Remember, Compiler always chooses the most specific method to invoke.
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.
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.
However, if you have two methods with parameter - String, and Integer,
then you would get ambiguity error for null, as compiler cannot decide
which one is more specific, as they are non-covariant types.
As described in Section 15.12.5 of JLS
Java try to use the most specific applicable version of a method.
String extends Object and so the method using String as parameter is always called.
If you try to add a method that take an Integer input it will throws error as ambiguous methods, because String and Integer both of them are more specific than Object but none is more specific than the other one
public void method1(String str) will get executed because object is string supperclass so the string method will be called.

JAVA Object/String method overload [duplicate]

This question already has answers here:
Method overloading and choosing the most specific type
(9 answers)
Why this behavior in overloading [duplicate]
(3 answers)
Closed 9 years ago.
Just out of curiosity I tried this example.
public class Class1 {
public void method(Object obj){
System.out.println("Object");
}
public void method(String str){
System.out.println("String");
}
public static void main(String... arg){
new Class1().method(null);
}
}
The output being "String". I want to know on what basis the JVM decides to invoke method taking String as argument and not Object.
Whenever more than one overloaded methods can be applied to the argument list, the most specific method is used.
In this case either of the methods can be called when passing null, since the "null type" is assignable to both Object and to String. The method that takes String is more specific so it will be picked.
Whenever there's Method Overloading, the JVM will search for the method from the most specific type to least specific type
See the JLS specification
15.12.2.5. Choosing the Most Specific Method
It is one of the puzzle of Java Puzzlers by Joshua Bloch - Puzzle 46: Case of the Confusing Constructor
Java Compiler chooses the most specific method.
String is a more specific type compared to the Object.
Becaue you are passing null in calling method and you defined void method(String str)
And String always initlize with null. it will find that matching parametrized method.
Thats y u got "str" on console.
When you are doing method overloading, jvm tries to the next in hierarchy. For e.g. if you overload methods with long and int, but invoke method by passing byte, it will first go to int as it is next in hierarchy to byte.
It's because of method Overloading
The most specific method is chosen at compile time.
As 'java.lang.String' is a more specific type than 'java.lang.Object'. In your case it returns String.

reason the output with null in view [duplicate]

This question already has answers here:
Which overload will get selected for null in Java?
(3 answers)
Closed 9 years ago.
I have the following code snippet:
public static void foo(Object x) {
System.out.println("Obj");
}
public static void foo(String x) {
System.out.println("Str");
}
If I call foo(null) why is there no ambiguity? Why does the program call foo(String x) instead of foo(Object x)?
why the program calls foo(String x) instead of foo(Object x)
That is because String class extends from Object and hence is more specific to Object. So, compiler decides to invoke that method. Remember, Compiler always chooses the most specific method to invoke. See Section 15.12.5 of JLS
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.
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.
However, if you have two methods with parameter - String, and Integer, then you would get ambiguity error for null, as compiler cannot decide which one is more specific, as they are non-covariant types.
The type of null is by definition a subtype of every other reference type. Quote JLS 4.1:
The null reference can always undergo a widening reference conversion to any reference type.
The resolution of the method signature involved in an invocation follows the principle of the most specific signature in the set of all compatible signatures. (JLS 15.12.2.5. Choosing the Most Specific Method).
Taken together this means that the String overload is chosen in your example.
It's calling the most specific method.
Since String is a subclass of Object, String is "more specific" than Object.
When given a choice between two methods where the argument is valid for both parameters, the compiler will always choose the most specific parameter as a match. In this case, null is a literal that can be handled as an Object and a String. String is more specific and a subclass of Object so the compiler uses it.

Using null in overloaded methods in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
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?
If 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:
question.method((String)null)
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 the String's one cause an int cannot be null and so its corresponding method is not eligible to be called in this case.
But if you change int for Integer, compiler will be confuse because both methods taking String is as accurate as Integer's one (orthogonal in hierarchy).
And the compiler can't (doesn't want? ^^) choose randomly.
First to understand why main.temp(null); resolves to temp(String s) and not temp(Object o) I point you at my old reply to Java method dispatch with null argument. Essentially, the literal null is of type nulltype and Object < String < nulltype. So null is closer to String then it is to Object.
Now, null is as close to String as it is to Integer, so when you add test(Integer) it becomes ambiguous

Categories

Resources