Advanced
Data Structures Algorithms & System Design(HLD+LLD)
by Logicmojo

Cracking FAANG companies interviews with a few months of preparation

Learn Advanced Data Structures, Algorithms & System Design

Online live classes from 4 to 7 months programs

Get job assistance after course completion

Download Course Brochure

Back to home
Logicmojo - Updated Jan 2, 2024



What do you mean by a method in Java? is a common question in Java. Simply put, a method is a short section of code that often performs one or more specialised functions and assists in segmenting a programme into distinct modules. In most cases, we require methods because we wish to employ the idea of code reusability. To illustrate, let's say we have developed a few lines of code that are commonly utilised in programmes. Therefore, we won't have to type the same

code repeatedly if we want to run it at different times with different values. Simply said, we write a function that has generic code that may be applied to, say, several parameters that are supplied through it. As a result, it won't affect performance.

What do you mean by method overloading in java?

The idea of method overloading enables the declaration of many methods in the same class with the same name but different parameters.
Java allows for method overloading, which always takes place in the same class (unlike method overriding).
Java allows polymorphism in part through the use of method overloading. The idea of polymorphism in object-oriented programming deals with several forms. Later on, we'll discuss polymorphism in more detail.
The number of parameters or the data type of the arguments can both be changed to avoid method overloading.
If two or more methods share the same name and parameter list but have different return types, overloading is not possible.

Here's an illustration:
Let's say we need to create a method to calculate the square of an integer. This approach can be expressed as follows:

public void SquareFunc( int number )
{
 int square = number * number;
 System.out.printIn("Method with Integer Argument Called:"+square);
}

It will output data of the integer data type.
Now, we wish to determine the square of a value of the type double.

public void doubleSquareFunc(double number)
{
 double square = number * number;
 System.out.printIn("Method with double Argument Called:"+square);
}

Similar to this, we must develop a different approach in order to find the square of a short type value.

public void shortSquareFunc(long number)
{ 
short square = number * number;
System.out.printIn("Method with short Argument Called:"+square);
}

If we take note of anything, it is obvious that we have chosen various names depending on the data type:

The software chooses which technique to use for each type of value, making it simpler for the programmer to obtain the same. We may achieve this by utilising the same name as well. It's not necessary to commit multiple typing methods to memory. The three methods mentioned above can all have the same name in Java.
And here is when method overloading comes into play.

The two approaches of method overloading are distinct.
Different datatype of arguments
Different number of arguments

By changing the Number of Parameters

The quantity of passed parameters can change how a method behaves. The example below demonstrates how method overloading with various argument counts can be implemented in method declaration and definition.

public class MultiplierClass {
    
    public int multiply(int a, int b) {
        return a * b;
    }
    
    public int multiply(int a, int b, int c) {
        return a * b * c;
    }
}

Changing the Data Type of Parameters

Modifying the data types of method parameters is another technique to implement method overloading. The example below demonstrates how to perform method overloading with several argument data types in method declaration and definition.

public class MultiplierClass {
    
    public int multiply(int a, int b) {
        return a * b;
    }
    
    public double multiply(double a, double b) {
        return a * b;
    }
}

Furthermore, both methods of method overloading may be used to define the MultiplierClass class:

public int multiply(int a, int b) { 
    return a * b; 
}
 
public double multiply(int a, int b) { 
    return a * b; 
}



Learn More

However, it's important to note that it's not possible to have two method implementations that simply differ in the nature of their returns.

The compiler in this situation wouldn't know which implementation of multiply() to call, therefore the code would simply not compile.

Why method overloading?

Let's think of scenario

int addTwo(int first, int sec){
    //
}
int addThree(int first, int sec, int three){
    //
}
String addStrnum(int first, int sec){
    //
}

The so-called type promotion, also known as widening primitive conversion, is a useful function offered by method overloading.

Simply said, when the types of the parameters submitted to an overloaded method and a particular method implementation do not match, one type is implicitly promoted to another.

Consider the following multiply() method implementations to better understand how type promotion operates:

public double multiply(int a, long b) {
    return a * b;
}

public int multiply(int a, int b, int c) {
    return a * b * c;
}

As there isn't a corresponding implementation of the method with two int parameters in this scenario, invoking the method with two int arguments will now cause the second argument to be promoted to long.

Method Overloading Characteristics

The following are the mentioned characteristics:

      ⮞ Methods are bound during the compilation phase because method overloading uses static polymorphism.

      ⮞ Since binding of methods is done at compile-time and overloading has an impact at runtime, several operations, such as binding and checking, are not necessary.

      ⮞ Method overloading is not considered when a method's return value is changed only slightly. As a result, an ambiguity error occurs.

      ⮞ The actual method overloading takes into account the amount, sequence, and type of parameters.

Advantages of Method Overloading

The advantages suggested are listed below:

      ⮞ cuts down on execution time because binding is completed during compilation.

      ⮞ Flexibility is achieved by an overloading technique.

      ⮞ Because code reuse is made possible, memory is conserved.

      ⮞ Reduced level of code complexity. Consequently, it ensures code consistency.

Can static method overloading be done?

Static methods can indeed be overloaded as well. In the example below, a static method pet is overloaded with various types and quantities of parameters.

// Java application to demonstrate static method overloading in action
class static_overloading
{
	static String pet(String s1) 
	{ 
	    return ("I have a cat named: " +s1);
	}
	static String pet(String n1, String n2) 
	{
	    return ("I have two dogs named: " +n1+" and "+n2); 
	}
	static int pet (int num)
	{
	    return num+3;
	}
 
	public static void main(String args[])
	{
		System.out.println(pet("Ms. tommy"));
		System.out.println(pet("Scooby", "Frodo"));
		System.out.println("Total number of Pets: " +pet(2));
	}
}

Can Java main() be overloaded?

The main() method can, in fact, be overloaded. An easy way to accomplish overloading the main() function with additional parameters is seen in the example below.

class demo_main_overloading {
 
	//main 1 
	public static void main(String[] args)
	{
		System.out.println("Overloading from main 1");
		demo_main_overloading.main("User!");
	}
    //main 2
	public static void main(String arg1)
	{
		System.out.println("Hello, " + arg1 +" Overloading main 2");
		demo_main_overloading.main("Are you learning", " Main Method overloading!");
	}
	//main 3
	public static void main(String arg1, String arg2)
	{
	    System.out.println("Overloading main 3");
		System.out.println("Hi, " + arg1 + ", " + arg2);
	}
}

Support for Operator Overloading in Java?

Java does not provide user-defined overloaded operators, in contrast to C++. Java internally overburdens operators; the + operator, for instance, is overburdened for concatenation.

Things to keep in mind with method overloading

The return type of methods cannot be changed to accommodate method overloading.
The requirement that two overloaded methods have separate parameters is the most crucial rule of method overloading.

Return-type has nothing to do with method overloading.

Whether or not their return types are different, an Ambiguity Error occurs if a class in a programme contains two methods with the same signature. This indicates that method overloading and return-type are unrelated.

class Demo{
	int disp(int x){
		return x;	
	}
	double disp(int y){
		return y;
	}
	public static void main(String args[])
{
	Demo s = new Demo();
	System.out.printIn("Value of x : " + s.disp(5));
	System.out.printIn("Value of y : " + s.disp(6.5));
	}  
}

Methods Overloading and null errors

When working with objects, it is a general problem to be cautious when supplying arguments if the same name methods have reference type parameters.
You can see how a null value can result in an error when methods are overloaded in the example below.
Example:
For all reference types, the null value is the default value. It gave JVM, which reports errors, ambiguities.

public class Sample 
{ 
    public void test(Integer i) 
    { 
        System.out.println("test(Integer ) "); 
    } 
    public void test(String name) 
    { 
        System.out.println("test(String ) "); 
    } 
    public static void main(String [] args) 
    { 
        Sample obj = new Sample();  
        obj.test(null); 
    } 
}
  

The main cause of the build time problem in the aforementioned example is the use of Integer and String as parameters, which are not Java's primitive data types and do not support null values. Given that both methods in the aforementioned example accept null, the compiler is perplexed when a null value is supplied.
We may work around this, though, by passing a specified reference type rather than a value.Instead of giving a null value, we are passing a specified type argument in this case.

public class Sample_Method 
{ 
    public void test(Integer i) 
    { 
        System.out.println("Method ==> test(Integer)"); 
    } 
    public void test(String name) 
    { 
        System.out.println("Method ==> test(String) "); 
    } 
    public static void main(String [] args) 
    { 
        Sample_Method obj = new Sample_Method ();  
        Integer a = null;
        obj.test(a);
        String b = null;
        obj.test(b); 
    } 
}
   

Autoboxing during Method Overloading

You might encounter a situation in method overloading when a signature accepts a reference type or a primitive type as a formal parameter. The compiler first looks for a method that has one or more parameters with the same data type (s). If the compiler cannot identify a method with par ameter(s) of the same reference type (i.e. class or interface type) when you use the wrapper class Object as an actual argument, it then begins searching for a method with parameter(s) of the same primitive data type.

import java.io.*;

// Class 1

class Converter_Demo {

	// Method 1
	public void method(int i)
	{

	
		System.out.println("Primitive type int formal argument :" + i);
	}

	// Method 2
	public void method(Integer i)
	{

		
		System.out.println("Reference type Integer formal argument :" + i);
	}

	// Method 2
	
	public void method(long i)
	{

		System.out.println("Primitive type long formal argument :" + i);
	}
}

// Class 2
class Logicmojo {
	public static void main(String[] args)
	{

		Converter_Demo c = new Converter_Demo();

		c.method(10);
		c.method(new Integer(15));
		c.method(new Long(100));

	
		// c.method(new Short(15));
	}
}


Method Overloading with Widening

If the compiler is unable to locate any methods that match autoboxing, it next begins looking for method parameters that are of the wider primitive data type.

The overloaded method is being called in the example below with a formal argument of the same data type as the real argument, a primitive(int). With the argument of Long wrapped Object, we are calling another method. The compiler begins looking for a method with the identical reference type ( Long wrapper class). Considering that there are no methods that accept Long wrapper class parameters. Therefore, it looks for a method that can take an i nput of a primitive data type that is bigger than long. In this instance, it locates and calls a method with a primitive data type of float.

import java.io.*;
class Converter_Demo {

	// Method
	public void method(int i) {

		System.out.println("Primitive type int formal argument :" + i);
	}

	// Method 2
	
	public void method(float i) {

		
		System.out.println("Primitive type float formal argument :" + i);
	}
}

class Logicmojo {

	public static void main(String[] args) {

		
		Converter_Demo c = new Converter_Demo();

		
		c.method(10);
		c.method(new Long(100));
	}
}

Conclusions

The article used many scenarios and examples to describe Java's method overloading. We sincerely hope this tutorial was informative. Watch this space for more Java articles.

Good luck and happy learning!