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.
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.
public class Test{
public static void abc(String s) {
System.out.println("String");
}
public static void abc(Object s) {
System.out.println("OBject");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
abc(null);
}}
Output-String
I am Beginner in java,I am confused about the output of the above program.
Please explain me the reason of the output.
Early Binding (Binding most specific method at compile time).
When you overload methods, most specific method will be choosen. In your case the order of choosing is String >Object (since null can be of any reference type).
In the hierarchy, String is more specific than Object. Hence string got chosen. In fact Object is the least specific among all the java objects
Here is the JLS for the same
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
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.
..... [rules]
Java compiler chooses most specific overloaded method will be selected.It is called as early binding. Here, String extends Object class hence it is more specific. You can refer official Java Language Specification
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 concept you have used is overloading and Object is superclass for all the classes in java. So when you provide any specific implementation (in this case its String) along with general implementation (in this case its Object) then JVM goes with specific implementation by default.
If you want to try it out please replace abc(null); with abc(123);
In this case, output will be "OBject" as JVM can not find any specific implementation for integer so it goes with generalized one.
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)
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).
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.
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