Java Method Overloading and Wrapper Classes [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 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.

Related

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...

what does Object do in java? [duplicate]

This question already has answers here:
When overriding equals in Java, why does it not work to use a parameter other than Object?
(7 answers)
Overloaded method selection based on the parameter's real type
(7 answers)
Closed 6 years ago.
I have this code in java and I do not understand the meaning of the Object in the following code ...
Here is the code
public class Tester {
public static void main(String[] args) {
Foo foo1 = new Foo(1);
Foo foo2 = new Foo(2);
System.out.print(foo1.equals(foo2));
}
}
class Foo {
Integer code;
Foo(Integer c) {
code = c;
}
public boolean equals(Foo f) {
return false;
}
public boolean equals(Object f) {
return true;
}
}
When I run the code I get false
but when I remove
public boolean equals(Foo f) {
return false;
}
and run the code I get true...
Why is that and what is happening ?
Thanks
This is method overloading resolution. There are two method candidates, one that takes an Object and the other takes Foo, when you pass a Foo, the most specific method (the one that takes Foo) will be called.
When you remove the method that takes Foo, you won't have an overload any longer and because Foo is an Object (as any class in Java) the method will accept it.
Method Overloading. Most specific method gets chosen at run time.
As per Language specification most specific method chooses at run time.
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.
You are getting false because most specific method got choosen. That is the reason
public boolean equals(Foo f) {
return false;
}
This method called and returning false. When you remove this method,
public boolean equals(Object f) {
return true;
}
This gets called because every Foo is Object.
Because the compiler is going to invoke the most-specific method matching the parameters. When you have equals(Foo) that is more specific than equals(Object). When you remove equals(Foo) the equals(Object) is the only method that is still valid. It is also worth noting that Foo has an implicit parent class, java.lang.Object.
i think you don,t really understand object oriented programming, you should get a book on OOP to understand the consepts. check it-ebboks.com for some helpfull books
An objact is an instance of a class, take for instance a classroom of student offering the same subjects , if john doe is a memebr of that class that is he offers the courses in that class he is an instance of that class
public boolean equals(Foo f) {
return false;
}
is returning false no mattter what parameter you pass into it

Change default return of an object in Java

The default return of an object in Java is to return the toString method, is there a way to change this behavior to for example return a number or some other type or is this just a core unchangeable component of the language?
Test test = new Test();
blankMethod(test);
I am not sure why people are saying my assumption is wrong... if I Override the toString method of object it will output that new toString method...
#Override
public String toString() {
System.out.println("This method is run when the object is used as a parameter");
return "test";
}
The default return of an object in Java is to return the toString method
That's how PrintStream.println works. Any object in java extends java.lang.Object and therefore inherits Object behavior. In particular, any method which takes Object as an argument, also can take any object of another type. However, you can override any public or protected method defined in Object. In your case you should override toString() method in Test class, otherwise if you pass Test object to PrintWriter.println(), it'll use toString from superclass (Object in your case). So, if i understood your question correctly, the answer is no.
Update: your terminology is wrong. There is no default return of an object in java. Returning Object.toString is the default behavior only for PrintStream.println(Object).
Update2: more widely, Java doesn't support implicit type conversion except upcasting. In your case, Test extends Object, but it doesn't extend String (actually, String is final and therefore you can't extend it). So, if you try to pass Test object to method which only takes String, you'll get compilation error because String and Test belong to different branches of class hierarchy.
You are actually calling
PrintStream.println(Object x)
instead of
public void println(String x)
The PrintStream.println(Object x) implementation is below:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
The method calls String.valueOf(x) whose implementation is below:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Note that the Object.toString() method is being called.
Notes on implicit conversion
An Object is only implicitly converted to a String using the toString method when the string concatenation operator (+) is invoked. More exactly the conversion works as follows:
A value x of primitive type T is first converted to a reference value...
This reference value is then converted to type String by string conversion.
Now only reference values need to be considered.
If the reference is null, it is converted to the string "null" (four
ASCII characters n, u, l, l). Otherwise, the conversion is performed
as if by an invocation of the toString method of the referenced object
with no arguments; but if the result of invoking the toString method
is null, then the string "null" is used instead.
The toString method is defined by the primordial class Object"
Java Language Specification 15.18.1
One language (of many) that expand on the idea of implicit conversions is Scala which allows one to bring a conversion (e.g., A -> B) into scope which is then invoked whenever some type (A) is passed as an argument when a different type (B) is required.
This answers "why people are saying my assumption is wrong".
Here is a simple program:
public class Test {
public String toString(){
return "I am a Test object.";
}
public int add(int a, int b){
return a+b;
}
public static void main(String[] args) {
Test object = new Test();
System.out.println(object);
System.out.println(object.add(2,2));
System.out.println(adder(object));
}
public static int adder(Test test){
return test.add(3,5);
}
}
Output:
I am a Test object.
4
8
The System.out.println method has to turn its argument into a String, one way or another. If it is passed an object reference, it uses its toString() method. If it is passed a primitive, such as an int expression, it converts it in an appropriate way.
It is nothing to do with what is being returned.
It also has nothing to do with any automatic conversion on passing a reference as an argument. See the third line of output, which depends on using the Test reference I passed to adder as a Test, not a String.
If you want to change what println prints, do what I did above, and pass it something different.

Method overloading and passing null [duplicate]

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.

What is the output for the following Java program where null is passed as argument for the overloaded methods? [duplicate]

This question already has answers here:
Java method dispatch with null argument
(4 answers)
Closed 9 years ago.
public class Overloading {
public static void main(String[] args) {
Overloading o = new Overloading();
o.display(null);
}
void display(String s) {
System.out.println("String method called");
}
void display(Object obj) {
System.out.println("Object method called");
}
}
It is giving the output as "String method called". I need the explanation why?
Taken from the Java Spec:
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.
First of all: both methods are accessible (obviously) and applicable. They are both applicable, because null is of type nulltype, which is by definition a subtype of all types. String is more specific than Object, because String extends Object. If you would add the following, you will have a problem, because both Integer and String are equally "specific":
void display(Integer s) {
System.out.println("Integer method called");
}
Java will always find the most specific version of method that is available.
String extends Object, and therefore it is more specific.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5

Categories

Resources