Method overloading and passing null [duplicate] - java

This question already has answers here:
How to do method overloading for null argument?
(7 answers)
Closed 8 years ago.
I have the following 2 methods overloaded in a class :
public class Test{
public static void main(String []args) throws ParseException{
Test t = new Test();
t.testMethod(null);
}
public void testMethod(Object o){
System.out.println("Object");
}
public void testMethod(String s){
System.out.println("String");
}
}
When I invoke the method testMethod it print "String".
When I add one more overloaded method :
public void testMethod(StringBuilder sb){
System.out.println("String");
}
It throws me compiler error : The method testMethod is ambigous for type Test..
All this happens when I invoke the method with null
My questions are :
Why it prints String and not Object?
Why is there compilation error on adding third method?

Method resolution works by selecting the most specific method that is applicable for the given arguments. In your first case, String is more "specific" than Object (since it is a subclass of Object) and so the String method is chosen.
When you add another method that takes a StringBuilder, both that and the String method are equally "specific" (they are both direct subclasses of Object), so there is an ambiguity as to which should be chosen, hence the error.

Why it prints String and not Object?
The java compiler picks the method with the most specific or least generic argument. Since Object is the Superclass of all classes (including String), String class is picked.
Why is there compilation error on adding third method?
Since String and StringBuilder are below Object, the compiler will find the call ambiguous since both String and StringBuilder can accept null, the compiler fails to determine which method to call hence you get error during compilation.
If you try the same thing with IOException and FileNotFoundException instead of String and StringBuilder, you will find out that FileNotFoundException is picked since it is least generic.

In case1 String inherits from Object, they are in inheritance chain, null matches both, compiler chooses a more specific type - String.
In case 2 String and StringBuilder are not in inheritance chain, compiler cannot choose a more specific type.
Details of overloaded method resolution are described in JLS 15.12.2.

Related

Java Method Overloading and Wrapper Classes [duplicate]

This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 4 years ago.
Can some one please explain in more detail.
public class Car
{
public void disp(Object o)
{
System.out.println("Object called :");
}
public void disp(String s)
{
System.out.println("String called :"+s);
}
}
Calling the main method as below
public class CarMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Car car=new Car();
car.disp(null);
}
}
Output : String Called : null
2nd scenario if I will pass Integer instead of Object in disp(Object o) then i am getting error as "The method disp(Integer) is ambiguous for the type Car"
As per understanding Java wrapper plays the major role here, but need well explanations.
Please help.
Let us take both the cases one by one:
Case 1: When we have two disp overloaded function, one with parameter Object and other with parameter String:
public void disp(String s) { System.out.println("String called :"+s); }
public void disp(Object o) { System.out.println("Object called :"); }
In this case, it will refer to the most specific method. According to Java Docs JLS 15.12.2.5:
A method m1 is strictly more specific than another method m2 if and
only if m1 is more specific than m2 and m2 is not more specific than
m1.
So, in above case, the function accepting String is more specific then the one accepting Object, however, the opposite is not true.
Hence, in this case, when null is passed, it will go to the method with parameter String. But if you will pass (Object)null, it will go to the method with parameter Object.
car.disp(null); --> String called :null
car.disp((Object)null); --> Object called :
Case 2: When we have two disp overloaded function, one with parameter String and one with parameter Integer.
public void disp(String s) { System.out.println("String called :"+s); }
public void disp(Integer i) { System.out.println("Integer called :"+ i); }
In this case, as none of the method is more specific then the other and both the function can accept null value, an appropriate function can not be decided in case of null. However, if you will pass (Integer)null or (String)null, no ambiguity will be there and appropriate function can be called.
car.disp(null); --> Compile time error (The method disp(String) is ambiguous for the type Car)
car.disp((Integer)null); --> Integer called :null
car.disp((String)null); --> String called :null
As the commenters have pointed out, you don't have a disp(Integer..) method, and if you do provide that, the method call works fine with disp(12).
As for the question of disp(null), according to the Java language spec:
Overloaded methods and constructors are resolved at compile time by
picking the most specific method or constructor from those which are
applicable.
Basically String is more specific than Object, so even though both apply to null, the String version of the method gets picked.

Overloading or a normal method [duplicate]

This question already has answers here:
Is it possible to have different return types for a overloaded method?
(13 answers)
The relationship of overload and method return type in Java?
(4 answers)
Closed 6 years ago.
I am gonna put this question to have a clear idea about overloading Concept in java . As per my understanding while method resolution in overloading compiler will look for method signature that is it should have same method name and different argument types . But what if the return type is different ??
class Test{
public void m1(int i) {
System.out.println(" int arg");
}
public int m1(String s) {
System.out.println("String-arg");
return (5+10);
}
public static void main (String[] args) throws java.lang.Exception
{
Test t = new Test();
t.m1(5);
int i = t.m1("ani");
System.out.println(i);
}}
the above program is running perfectly . my doubt here is , the method m1() is it overloaded ?? it has different return type . someone please make it clear. Thanks in advance
In Java methods are identified by name and arguments' classes and amount. The return type doesn't identify the method. For this reason the following code would be illegal:
public void m1(String i) {
System.out.println(" int arg");
}
public int m1(String s) {
System.out.println("String-arg");
return (5+10);
}
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded. (...) When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4)
Summarizing, two methods with the same name can return different types, however it's not being taken into account when deciding which method to call. JVM first decides which method to call and later checks if the return type of that method can be assigned to the certain variable.
Example (try to avoid such constructions):
public int pingPong(int i) {
return i;
}
public String pingPong(String s) {
return s;
}
public boolean pingPong(boolean b) {
return b;
}
if we follow the Oracle definition then yes, it is a overloaded method
here the info (emphasis mine)
The Java programming language supports overloading methods, and Java
can distinguish between methods with different method signatures. This
means that methods within a class can have the same name if they have
different parameter lists (there are some qualifications to this that
will be discussed in the lesson titled "Interfaces and Inheritance").
the fact that the method return a value or not is IRRELEVANT for the overloading definition...
another thing is here why can a method somethimes return a value and sometimes no...
this will drive crazy the people using the code, but that is another question...

Why Netbeans gives a compile time error and cmd compiles the same program without a issue? [duplicate]

I have added three methods with parameters:
public static void doSomething(Object obj) {
System.out.println("Object called");
}
public static void doSomething(char[] obj) {
System.out.println("Array called");
}
public static void doSomething(Integer obj) {
System.out.println("Integer called");
}
When I am calling doSomething(null) , then compiler throws error as ambiguous methods. So is the issue because Integer and char[] methods or Integer and Object methods?
Java will always try to use the most specific applicable version of a method that's available (see JLS §15.12.2).
Object, char[] and Integer can all take null as a valid value. Therefore all 3 version are applicable, so Java will have to find the most specific one.
Since Object is the super-type of char[], the array version is more specific than the Object-version. So if only those two methods exist, the char[] version will be chosen.
When both the char[] and Integer versions are available, then both of them are more specific than Object but none is more specific than the other, so Java can't decide which one to call. In this case you'll have to explicitly mention which one you want to call by casting the argument to the appropriate type.
Note that in practice this problem occurs far more seldom than one might think. The reason for this is that it only happens when you're explicitly calling a method with null or with a variable of a rather un-specific type (such as Object).
On the contrary, the following invocation would be perfectly unambiguous:
char[] x = null;
doSomething(x);
Although you're still passing the value null, Java knows exactly which method to call, since it will take the type of the variable into account.
Each pair of these three methods is ambiguous by itself when called with a null argument. Because each parameter type is a reference type.
The following are the three ways to call one specific method of yours with null.
doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
May I suggest to remove this ambiguity if you actually plan to call these methods with null arguments. Such a design invites errors in the future.
null is a valid value for any of the three types; so the compiler cannot decide which function to use. Use something like doSomething((Object)null) or doSomething((Integer)null) instead.
Every class in Java extends Object class.Even Integer class also extends Object. Hence both Object and Integer are considered as Object instance. So when you pass null as a parameter than compiler gets confused that which object method to call i.e. With parameter Object or parameter Integer since they both are object and their reference can be null. But the primitives in java does not extends Object.
I Have tried this and when there is exactly one pair of overloaded method and one of them has a parameter type Object then the compiler will always select the method with more specific type. But when there is more than one specific type, then the compiler throws an ambiguous method error.
Since this is a compile time event, this can only happen when one intentionally passes null to this method. If this is done intentionally then it is better to overload this method again with no parameter or create another method altogether.
class Sample{
public static void main (String[] args) {
Sample s = new Sample();
s.printVal(null);
}
public static void printVal(Object i){
System.out.println("obj called "+i);
}
public static void printVal(Integer i){
System.out.println("Int called "+i);
}
}
The output is Int called null and so ambiguity is with char[] and Integer
there is an ambiguity because of doSomething(char[] obj) and doSomething(Integer obj).
char[] and Integer both are the same superior for null that's why they are ambiguous.

Passing null reference in a method parameter in java? [duplicate]

This question already has answers here:
Which overload will get selected for null in Java?
(3 answers)
Closed 8 years ago.
When i run this code the output is "String"; if I hide the method that accepts a String parameter and run the code again then the output is "Object", so can anyone please explain me how this code works?
public class Example {
static void method(Object obj) {
System.out.println("Object");
}
static void method(String str) {
System.out.println("String");
}
public static void main(String args[]) {
method(null);
}
}
Compiler will choose most specific method, in this case, String is a sub class of Object, so the method with String as argument will be invoked.
From 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.
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.

Java resolving overloaded method invocation when value null is used as argument [duplicate]

I have added three methods with parameters:
public static void doSomething(Object obj) {
System.out.println("Object called");
}
public static void doSomething(char[] obj) {
System.out.println("Array called");
}
public static void doSomething(Integer obj) {
System.out.println("Integer called");
}
When I am calling doSomething(null) , then compiler throws error as ambiguous methods. So is the issue because Integer and char[] methods or Integer and Object methods?
Java will always try to use the most specific applicable version of a method that's available (see JLS §15.12.2).
Object, char[] and Integer can all take null as a valid value. Therefore all 3 version are applicable, so Java will have to find the most specific one.
Since Object is the super-type of char[], the array version is more specific than the Object-version. So if only those two methods exist, the char[] version will be chosen.
When both the char[] and Integer versions are available, then both of them are more specific than Object but none is more specific than the other, so Java can't decide which one to call. In this case you'll have to explicitly mention which one you want to call by casting the argument to the appropriate type.
Note that in practice this problem occurs far more seldom than one might think. The reason for this is that it only happens when you're explicitly calling a method with null or with a variable of a rather un-specific type (such as Object).
On the contrary, the following invocation would be perfectly unambiguous:
char[] x = null;
doSomething(x);
Although you're still passing the value null, Java knows exactly which method to call, since it will take the type of the variable into account.
Each pair of these three methods is ambiguous by itself when called with a null argument. Because each parameter type is a reference type.
The following are the three ways to call one specific method of yours with null.
doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
May I suggest to remove this ambiguity if you actually plan to call these methods with null arguments. Such a design invites errors in the future.
null is a valid value for any of the three types; so the compiler cannot decide which function to use. Use something like doSomething((Object)null) or doSomething((Integer)null) instead.
Every class in Java extends Object class.Even Integer class also extends Object. Hence both Object and Integer are considered as Object instance. So when you pass null as a parameter than compiler gets confused that which object method to call i.e. With parameter Object or parameter Integer since they both are object and their reference can be null. But the primitives in java does not extends Object.
I Have tried this and when there is exactly one pair of overloaded method and one of them has a parameter type Object then the compiler will always select the method with more specific type. But when there is more than one specific type, then the compiler throws an ambiguous method error.
Since this is a compile time event, this can only happen when one intentionally passes null to this method. If this is done intentionally then it is better to overload this method again with no parameter or create another method altogether.
class Sample{
public static void main (String[] args) {
Sample s = new Sample();
s.printVal(null);
}
public static void printVal(Object i){
System.out.println("obj called "+i);
}
public static void printVal(Integer i){
System.out.println("Int called "+i);
}
}
The output is Int called null and so ambiguity is with char[] and Integer
there is an ambiguity because of doSomething(char[] obj) and doSomething(Integer obj).
char[] and Integer both are the same superior for null that's why they are ambiguous.

Categories

Resources