Method Overloading in Java with Examples
Introduction
(Note - This tutorial builds on Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values.) What is method overloading? Method overloading means defining several methods in the same class with the same name but different parameter lists. The compiler tells them apart by their signatures - the name plus the parameter types - and picks the right one for each call based on the arguments. The rules are -
OUTPUT of the above code
The three calls look alike, but each has a different number of arguments, so the compiler calls a different method each time. Without overloading, we would need three names, such as
Overloading by type and order of parameters
OUTPUT of the above code
Overloading by the order of types, as in the last two methods, is legal but easy to misuse - a caller who swaps two arguments silently gets a different method. Use it sparingly.
What does not count as overloading
Methods which differ only in their return type, or in parameter names, have the same signature - so declaring both is a compile error.
OUTPUT on compiling the above code
If this were allowed, the compiler could not tell which method
How the compiler chooses an overloaded method
When no method matches the argument types exactly, the compiler looks for the most specific method it can use, in three phases -
OUTPUT of the above code
Explanation of the code
OUTPUT on compiling the above code
Both methods need one widening conversion for
System.out.println() prints a String, an int, a double or a char - yet you always call it by the same name. That works because println() is overloaded: PrintStream has a separate println() method for each type. This tutorial explains method overloading in Java with examples. We will start with what overloading is and the rules for it. We will then overload methods by the number and by the types of parameters. Next we will see how the compiler chooses which overloaded method to call - including widening, boxing and varargs - and the ambiguous calls it rejects. Lastly, we will go through best practices.(Note - This tutorial builds on Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values.) What is method overloading? Method overloading means defining several methods in the same class with the same name but different parameter lists. The compiler tells them apart by their signatures - the name plus the parameter types - and picks the right one for each call based on the arguments. The rules are -
- Overloaded methods must differ in the number, the types, or the order of types of their parameters.
- A different return type alone is not enough, and neither are different parameter names.
- Overloaded methods may have different return types, access modifiers and
static-ness, as long as the parameter lists differ.
Overloading by the number of parameters
//AreaCalculator.java
public class AreaCalculator {
static double area(double side) { // square
return side * side;
}
static double area(double length, double width) { // rectangle
return length * width;
}
static double area(double a, double b, double c) { // triangle, from its three sides
double s = (a + b + c) / 2;
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
public static void main(String[] args) {
System.out.println("Square 4 : " + area(4));
System.out.println("Rectangle 4 x 6 : " + area(4, 6));
System.out.println("Triangle 3-4-5 : " + area(3, 4, 5));
}
}
Square 4 : 16.0 Rectangle 4 x 6 : 24.0 Triangle 3-4-5 : 6.0
squareArea(), rectangleArea() and triangleArea().
Overloading by parameter types
//Formatter.java
public class Formatter {
static String describe(int value) {
return "int " + value;
}
static String describe(double value) {
return "double " + value;
}
static String describe(String value) {
return "String \"" + value + "\"";
}
static String describe(String label, int count) {
return label + " x" + count;
}
static String describe(int count, String label) { // same types, different order
return count + " of " + label;
}
public static void main(String[] args) {
System.out.println(describe(42));
System.out.println(describe(4.2));
System.out.println(describe("Java"));
System.out.println(describe("Books", 3));
System.out.println(describe(3, "Books"));
}
}
int 42 double 4.2 String "Java" Books x3 3 of Books
Methods that differ only in return type
//BadOverload.java
public class BadOverload {
static int parse(String text) {
return Integer.parseInt(text);
}
static double parse(String text) {
return Double.parseDouble(text);
}
}
BadOverload.java:7: error: method parse(String) is already defined in class BadOverload
static double parse(String text) {
^
1 error
parse("42"); means - the return value is not even used. Give methods with different results different names, such as parseInt() and parseDouble().
- Exact match or widening - an exact type match, or a widening conversionClick to read tutorial: Type Conversion and Casting in Java with Examples such as
inttolongordouble. If several methods qualify, the one with the "narrowest" widening wins. - Boxing and unboxing - only if phase 1 finds nothing, conversions such as
inttoIntegerare allowed. - Varargs - only if phases 1 and 2 find nothing, methods with variable-length arguments are considered.
Which overloaded method gets called?
//OverloadResolution.java
public class OverloadResolution {
static void show(long x) { System.out.println("show(long) <- " + x); }
static void show(double x) { System.out.println("show(double) <- " + x); }
static void show(Integer x) { System.out.println("show(Integer) <- " + x); }
static void show(Object x) { System.out.println("show(Object) <- " + x); }
static void show(int... xs) { System.out.println("show(int...) <- " + xs.length + " values"); }
public static void main(String[] args) {
int i = 5;
show(i); // int -> long wins over int -> double, and over boxing
show(5.0f); // float -> double (widening)
show(Integer.valueOf(7)); // exact match
show("text"); // String -> Object
show('A'); // char -> long (widening)
show(); // only varargs can take zero arguments
show(1, 2, 3); // only varargs can take three
}
}
show(long) <- 5 show(double) <- 5.0 show(Integer) <- 7 show(Object) <- text show(long) <- 65 show(int...) <- 0 values show(int...) <- 3 values
show(i)with anintchoseshow(long). Widening (phase 1) beats boxing toInteger(phase 2), andlongis a more specific widening ofintthandouble.show('A')also choseshow(long), printing the character's code, 65 - acharwidens to a number, not to aString.- The varargs method was used only when no other method could take the arguments. Varargs are covered in Java VarargsClick to read tutorial: Java Varargs: Variable-Length Arguments with Examples.
An ambiguous overloaded call
//Ambiguous.java
public class Ambiguous {
static void pay(int amount, double rate) { }
static void pay(double amount, int rate) { }
public static void main(String[] args) {
pay(100, 5);
}
}
Ambiguous.java:7: error: reference to pay is ambiguous
pay(100, 5);
^
both method pay(int,double) in Ambiguous and method pay(double,int) in Ambiguous match
1 error
pay(100, 5), so neither is more specific. Calling pay(100, 5.0) would choose the first. The same error occurs when null is passed to methods taking, say, a String and an Integer.
Best practices
- Overloads should do the same thing: all methods with one name should perform the same operation on different inputs, like
println()andMath.max(). - Delegate to one main version: let simpler overloads call the most complete one with default values, so the logic lives in one place - for example
greet(name)callinggreet(name, "Hello"). - Avoid confusing combinations: overloads with the same number of parameters whose types can convert into each other -
int/long,int/Integer, or swapped orders - make it hard to know which one runs. - Overloading is not overriding: overriding is a subclass replacing an inherited method with the same signature, decided at runtime. See the @Override annotation tutorialClick to read tutorial on the @Override annotation.
Java Fundamentals Tutorials
Is Java Pass-by-Value or Pass-by-Reference?Click to read tutorial: Is Java Pass-by-Value or Pass-by-Reference? Java Varargs: Variable-Length Arguments with ExamplesClick to read tutorial: Java Varargs: Variable-Length Arguments with Examples Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values Recursion in Java with ExamplesClick to read tutorial: Recursion in Java with Examples Static vs Instance Methods in JavaClick to read tutorial: Static vs Instance Methods in Java What is Java? History, Features, Editions and UsesClick to read tutorial: What is Java? History, Features, Editions and Uses
Is Java Pass-by-Value or Pass-by-Reference?Click to read tutorial: Is Java Pass-by-Value or Pass-by-Reference? Java Varargs: Variable-Length Arguments with ExamplesClick to read tutorial: Java Varargs: Variable-Length Arguments with Examples Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values Recursion in Java with ExamplesClick to read tutorial: Recursion in Java with Examples Static vs Instance Methods in JavaClick to read tutorial: Static vs Instance Methods in Java What is Java? History, Features, Editions and UsesClick to read tutorial: What is Java? History, Features, Editions and Uses