Method Overloading
Method Overloading
In the previous lessons you learned how to define methods with parameters and return values. Now imagine you want to write a method that adds two numbers — but sometimes those numbers are int values and sometimes they are double values. Do you have to give those two methods completely different names? In Java, the answer is no. Method overloading lets you give several methods the same name as long as their parameter lists are different.
What Is Method Overloading?
Method overloading means defining two or more methods in the same class with the same name but different parameter lists. The parameter lists must differ in at least one of these ways:
- The number of parameters is different.
- The type of at least one parameter is different.
- The order of parameter types is different (less common, but valid).
A Simple Example
Here is a class with three overloaded versions of an add method:
All three methods are named add, yet the compiler never gets confused. When it sees add(3, 4) it knows you are passing two int values, so it picks version 1. When it sees add(1.5, 2.5) the literals are double, so it picks version 3.
How Overload Resolution Works
The process of choosing which overloaded method to call is called overload resolution, and it happens entirely at compile time. The compiler looks at the types of the arguments you supply and finds the most specific matching method. The rules, simplified:
- Exact match first — if an overload whose parameter types match exactly exists, it wins.
- Widening promotion — if no exact match exists, the compiler tries to widen primitive types (e.g.
int→long→float→double) to find a match. - Autoboxing — as a last resort before varargs, the compiler tries boxing/unboxing (e.g.
int→Integer).
Overloading With Different Parameter Types and Order
You can also overload by changing the order of types. This is valid but usually a sign of a design problem — it is easy to pass arguments in the wrong order by accident:
printLabeled vs printIndexed) or a single method with a clearer signature instead.
A Real-World Use Case: Logging
Overloading shines when you want a method to accept different levels of detail without forcing callers to always supply everything. Here is a small logger that lets you log with just a message, or with a message and an exception:
The caller chooses the right level of detail and uses the same name, log, in both cases. This is cleaner than two differently named methods (logInfo and logError) when the core concept is the same action.
What Overloading Is Not
It is worth drawing a clear boundary:
- Overloading (this lesson) — same name, different parameter list, resolved at compile time.
- Overriding (a future lesson on inheritance) — same name AND same parameter list in a subclass, resolved at runtime via polymorphism.
These two concepts are often confused but they are completely different mechanisms. Overloading is about giving callers a convenient API; overriding is about changing inherited behaviour.
Summary
Method overloading lets you use the same method name for logically related operations that differ only in the type or number of inputs. The compiler resolves which version to call at compile time by matching the argument types to the parameter list. Use it to create cleaner, more readable APIs — but keep your overloads distinct enough that the right choice is always obvious.