Scientech Easy Automatic Type Promotion in Method Overloading Java | Scientech Easy

Friday, March 15, 2019

Automatic Type Promotion in Method Overloading Java

In the previous tutorial, you learned that Java performs type conversion when you perform an arithmetic operation with unlike data types. For example, when you add an int and a  double, the result is a double.
In a similar way, when you pass an argument to a method, Java can promote one data type to another. For example, If a method has a double parameter and you are passing in an integer, the compiler promotes an integer to a double. 
The automatic type promotion in method overloading concept is very important for an interview purpose because there is always asked one to two questions based on this concept in the interview whether it is a technical test or technical interview. So, let's start in detail.

Method Overloading with Type Promotion in Java


While resolving overloaded methods if the exact match method is not available, you will not immediately get any compile time error. First, the compiler promotes lower type argument to the higher type argument and checks whether the match method is available or not. If the match method is available, it will be considered.

If the match method is not available, compiler promotes argument once again to the higher type. This process will be continued until all possible promotions are not checked. Still, if the match method is not available, you will get compile time error. This process is called automatic type promotion in method overloading.
The following possible promotions for the method overloading is shown in the below figure.
Type promotion in method overloading java
Let's see different cases with practical example programs based on this concept.
Case 1:
Program source code 1:
    package methodOverloading; public class TypePro { static void m1(double a){ System.out.println("double-arg"); } static void m1(int a){ System.out.println("int-arg"); } public static void main(String[] args) { m1(2); // Exact match is found because 2 is an integer data type. So, the output is int-arg. m1 (1.5f); // Exact match is found because 1.5f is an float data type. So, the output is double-arg. } }
    Output: int-arg double-arg
Program source code 2:
    package methodOverloading; public class TypePro { public void m1(double a){ System.out.println(a*a); } public void m1(float a){ System.out.println(a*a); } public static void main(String[] args) { TypePro t=new TypePro(); t.m1(2); // Exact match is not found for passing argument 2 because 2 is an integer data type. } }
    Output: 4.0
Key points: 
1. When an exact match is not found for passing argument then the compiler finds the method with the smallest argument. 
2. In the above example, float and double both belong to float category data type. Due to which an exact match is not found for passing argument 2 because 2 is an integer data type. Therefore, the compiler finds the method with the smallest argument float rather than double. The float data type is a smaller size than double and consumes less memory.
Program source code 3:

    package methodOverloading; public class TypePro { public void m1(double a){ System.out.println(a+a); } public void m1(short a){ System.out.println(a+a); } public static void main(String[] args) { TypePro t=new TypePro(); t.m1(2); // Exact match is not found for passing argument 2 because 2 is an integer data type. } }
    Output: 4.0
Key points: 
1. In this program, 2 is an integer whereas short belongs to integer category data type but small size primitive data type and double belongs to the float category data type. So, the exact match is not found.
2. Since the int (large size primitive data type) cannot be promoted to short (small size primitive data type). Therefore, 2 cannot be promoted to the short. 
3. Since the small size primitive data type can be promoted to large size primitive data type. Therefore, 2 will be promoted to double and the compiler will call the method with a double argument.
Program source code 4:
    package methodOverloading; public class TypePro { public void m1(byte a){ System.out.println(a+a); } public void m1(short a){ System.out.println(a+a); } public static void main(String[] args) { TypePro t=new TypePro(); t.m1(10); // Exact match is not found because the method m1(byte) is not applicable for the argument (int). } }
    Output: Compile time error 
Key points: 
Since short and byte both are small size data types than int. Therefore, 10 cannot be promoted to them. The compiler will generate compile time error.
Recommended for You


Program source code 5:
    package methodOverloading; public class TypePro { public void m1(int i){ System.out.println("Hello"); } public void m1(float f){ System.out.println("Java"); } public static void main(String[] args) { TypePro t=new TypePro(); t.m1(10); t.m1(10.5f); t.m1('a'); t.m1(10l); // t.m1(10.5); // Compile time error. } }
    Output: Hello Java Hello Java
Case 2:
Program source code 6:
    package methodOverloading; public class TypePro { public void m1(String s){ System.out.println("Hello"); } public void m1(Object o){ System.out.println("Java"); } public static void main(String[] args) { TypePro t=new TypePro(); t.m1(new Object()); // Exact match with object argument. t.m1("Deep"); // Exact match with string argument. t.m1(10); t.m1(10.5f); t.m1('a'); t.m1(null); } }
    Output: Java Hello Java Java Java Hello
Key points:
1. The primitive data types such as boolean, byte, char, short, int, long, float, and double can be promoted to object.
2. In the case of null, null is valid for both string and object. So, which method will be called?
Since the object is the superclass of all the classes in Java. Thus, the object is a parent class and string is a child class. While resolving the overloading method, the compiler always uses the presidency for the child type argument. So, the compiler will call the method with the string argument.
Case 3:
Program source code 7:
    package methodOverloading; public class TypePro { public void m1(String s){ System.out.println("Hello"); } public void m1(StringBuffer s){ System.out.println("Java"); } public static void main(String[] args) { TypePro t=new TypePro(); // t.m1(new Object() ); // Exact match not found because The method m1(String) is not applicable with object argument. t.m1("Deep"); // Exact match with string argument t.m1(new StringBuffer()); // Exact match with string buffer parameter. // t.m1(null); // The method m1(String) is ambiguous for the type TypePro. } }
    Output: Hello Java
 Key points:
1. The object is the parent class of both string class and the StringBuffer class. Here, String and StringBuffer both are child classes of the object class at the same level. There is also no parent-child relationship between string and string buffer. So, both methods are matched at the same level. Therefore, the compiler is ambiguous for which method will be called?

Case 4:
Program source code 8:
    package methodOverloading; public class Sum { public void add(int a, float b){ System.out.println(a+b); } public void add(float b, int a){ System.out.println(a+b); } public static void main(String[] args) { Sum s=new Sum(); s.add(10, 5.5f); // Exact matched. s.add(10.5f, 1); // Exact matched. // s.add(10, 10); // Ambiguous because both methods are matched. 10 is an int and can be promoted to float. // s.add(10.5f, 10.2f); // No matched. // Compile time error. } }
    Output: 15.5 11.5
Case 5:
Program source code 9:
    package methodOverloading; public class Sum { public void add(int x){ System.out.println(x+x); } public void add(int... x){ // We can call this method by passing any int value including zero. System.out.println(x); } public static void main(String[] args) { Sum s=new Sum(); s.add(0); // Exact matched. s.add(10); // Exact matched. } }
    Output: 0 20
Case 6:
Program source code 10:
    package methodOverloading; public class Animal { } package methodOverloading; public class Lion extends Animal { } package methodOverloading; public class FoodTest { public void food(Animal a){ System.out.println("Animals eat vegetarian and non-vegetarian food"); } public void food(Lion l){ System.out.println("Lions eat non-vegetarian food"); } public static void main(String[] args) { FoodTest ft=new FoodTest(); Animal a=new Animal(); // a is reference variable of Animal class and it is pointing the objects of Animal. ft.food(a); // Exact matched. Lion l=new Lion(); // l is reference variable of Lion class and it is pointing to the objects of Lion. ft.food(l); // Exact matched. Animal a1=new Animal(); ft.food(a1); // Exact matched. ft.food(null); // Exact matched. } }
    Output: Animals eat vegetarian and non-vegetarian food Lions eat non-vegetarian food Animals eat vegetarian and non-vegetarian food Lions eat non-vegetarian food
Key points: 
1. In method overloading, the resolution is always taken care of the compiler based on the reference type only. Runtime object never plays any role in overloading.
2. In the case of null, Animal is the superclass of Lion class. See key points 2 of program 6.

Final words 

Hope that this article has covered almost all practical example programs related to automatic type conversion in method overloading Java. We hope that you have enjoyed this article.
Thanks for reading!