Search This Blog

Method Overloading in Java with Examples

In Java, it is possible to define two or more methods within the same class that share the same name, as long as their parameter declarations are different. When this is the case, the methods are said to be overloaded, and the process is referred to as method overloading. The compiler will resolve the call to a correct method depending on the actual number and/or types of the passed parameters.

The main advantage of method overloading increases the readability of the program.

Method overloading is one of the ways that Java supports polymorphism. If you have never used a language that allows the overloading of methods, then the concept may seem strange at first. But as you will see, method overloading is one of Java’s most exciting and useful features.

When an overloaded method is invoked, Java uses the type and/or a number of arguments as its guide to determine which version of the overloaded method to actually call. Thus, overloaded methods must differ in the type and/or a number of their parameters.

You cannot overload methods with the methods differing in return types alone.

You cannot overload methods with the methods differing in exception specifications alone.

No parameters
a: 10
a and b: 10 20
double a: 123.25
Result of ob.test(123.25): 15190.5625

As you can see, test( ) is overloaded four times. The first version takes no parameters, the second takes one integer parameter, the third takes two integer parameters, and the fourth takes one double parameter. The fact that the fourth version of test( ) also returns a value is of no consequence relative to overloading since return types do not play a role in overload resolution.

Three ways to overload a method

In order to overload a method, the argument lists of the methods must differ in either of these:

Number of parameters.

Data type of parameters.

Sequence of Data type of parameters

1. Different Number of parameters

In this example, we will overload 3 version of average() methods with a different number of parameters.

In the first method call, the statement is aMethod(b) where the variable b is of type byte. There is no aMethod definition that takes byte as an argument. The closest type (in size) is a short type and not int, so the compiler resolves the call aMethod(b) to aMethod(short val) definition.

In the second method call, the statement is aMethod(9). The constant value 9 is of type int. The closest match is aMethod(int), so the compiler resolves the call aMethod(9) to aMethod(int val) definition.

The third method call is aMethod(i), where the variable i is of type Integer. There is no aMethod definition that takes Integer as an argument. The closest match is aMethod(Object val), so it is called. Why not aMethod(int val)? For finding the closest match, the compiler allows implicit upcasts, not downcasts, so aMethod(int val) is not considered.

The last method call is aMethod("9"). The argument is a String type. Since there is an exact match, aMethod(String val) is called.

This process of the compiler trying to resolve the method call from given overloaded method definitions is called overload resolution. For resolving a method call, it first looks for the exact match—the method definition with an exactly the same number of parameters and types of parameters. If it can’t find an exact match, it looks for the closest match by using upcasts.

Method Overloading and Type Promotion

One type is promoted to another implicitly if no matching datatype is found. Let's understand the concept by the figure given below:

As displayed in the above diagram, the sequence of each type promotion:

The method aMethod(byte) in the type MethodOverloading is not applicable for the arguments (int)

The type of constant 9 is int, so there is no matching definition for aMethod for the call aMethod(9). As you saw earlier with respect to the overload resolution, the compiler can do upcasts (e.g., byte to int) for the closest match, but it does not consider downcasts (e.g., int to byte or int to short, as in this case). Hence, the compiler does not find any matches and throws you an error.

Why did this call become an “ambiguous” call? The constants 9 and 10 are ints. There are two aMethod definitions: one is aMethod(long, int) and another is aMethod(int, long). So there is no exact match for the call aMethod(int, int). An integer can be implicitly upcasted to both long as well as Integer. Which one will the compiler choose? Since there are two matches, the compiler complains with an error that the call is ambiguous.

Summary

Method Overloading is a feature that allows a class to have more than one method having the same name if their argument lists are different.

In order to overload a method, the argument lists of the methods must differ in either of these: Number of parameters, Data type of parameters and Sequence of Data type of parameters

Overload resolution takes place entirely at compile time.

You cannot overload methods with the methods differing in return types alone.

You cannot overload methods with the methods differing in exception specifications alone.

For overload resolution to succeed, you need to define methods such that the compiler finds one exact match. If the compiler finds no matches for your call or if the matching is ambiguous, the overload resolution fails and the compiler issues an error.