undefined

Overloading methods | part 2

Java Core
Level 5 , Lesson 3
Available

"Hello, Amigo! A couple of days ago I told you about overloading methods. Did you understand everything?"

"Yes. I remember. Each class method must be unique. A member method is unique if the class has no other method with the same name and parameter types (and the order of the parameters matters)."

"Very good! I see you've learned that lesson well. Today I want to expand your knowledge in this topic just a bit. What method do you think will be called in each case?"

Code
class Cat
{
 public static void print(int n)
 {
  System.out.println(n);
 }
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }
public static void main(String[] args)
{
  Cat.print(1);
  Cat.print((byte)1);
  Cat.print("1");
  Cat.print(null);
 }
}

"It's hard to say."

"In the first case, 1 is an int. We have a 100% match with the method that takes an int. The first void print(int n). will be called.

In the second case, we don't have a method that takes a byte. But there are two methods that take a short and an int. Based on type widening rules, a byte will first be widened to a short, and then widened to an int. Thus, the verdict is that the void print(short n). will be called.

In the third case, we have a 100% match with the method that takes a String. The void print(String s). method will be called.

The fourth case is ambiguous. null doesn't have a specific type. The compiler will refuse to compile this code. In this case, we need to write Cat.print((Integer)null) to call the third method and Cat.print((String)null) to call the fourth."

"That was very informative. Thank you."

"I'd like to point out that when determining the correct method to call, types can only widen. They cannot narrow. Consider this example:"

Code
class Cat
{
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }

 public static void main(String[] args)
 {
  Cat.print((byte)1);
  Cat.print(1);
 }
}

In the first case, the byte type will be widened to a short and the first method will be called: void print(short n)..

In the second case, there will be an implicit widening conversion from int to Integer, and then the second method will be called: void print(Integer n)..

"I didn't expect that."

"No, here's the real surprise:"

Java code Description
 class Cat
{
 public static void print(Object o)
 {
  System.out.println(o);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }

 public static void main(String[] args)
 {
  Cat.print(1);
  Cat.print(null);
 }
}
In the first case, int will be extended to Integer. Because there is no method for Integer, the most suitable method (and the one called) is void print(Object o)

In the second case, there won't be any compilation errors and void print(String s) will be called, which is somewhat not obvious.

"Amigo, I hope you understand that in such cases it's best to specify a type cast operator (as in we did with «(byte)») in order to know exactly which method will be called."

"I never expected any problems would come from overloading methods. But then you come along. Thanks, Rishi. I'll keep up my guard on this point."

Comments (17)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Gellert Varga Level 18 Szekesfehervar Hungary
7 March 2021
In the last example, why doesn't Cat.print(null) cause a compiler error, and why don't we need to cast the "null" to a String or Object type before we send it to the methods? Even though both the print(Object o) and print(String s) methods would be able to receive the null reference. Answer: String is a descendant of Object, and in this case the JVM is able to decide which method to use. JVM chooses the one that is under the other one on the chain of inheritance. Which requires the fewest widening conversions.
Agent Smith Level 38
28 August 2020
Good lesson, today I learned.
Nicola Level 17 Vienna Austria
27 October 2019
I don't gent the last example. If type can only widen, why Cat.print(1) call void print(Object o)?
15 August 2019
my head's exploding in 3... 2... 1...
Ed Maphis Level 20 Painesville United States
5 June 2019
You probably shouldn't write programs the rely on this behavour.
Darko Jakimovski Level 18 Kriva Palanka Macedonia The Former Yugoslav Republic of
15 May 2019
I don't understand why in the first case it's an error to call the method with a "null" as a parameter and in the second case it doesn't :/ It's the same thing
Tayyab Mubeen Level 16 Lahore Pakistan
12 November 2018
Type cast is necessary when we are doing method overloading...!!!