Method Overloading in Java: Rules, Resolution and Examples
Difficulty: Beginner–Intermediate · Importance: High · Java version: Java 1.0+ (boxing and varargs in overload resolution: Java 5+) · Last updated: 1 Nov 2026
Output puzzle (asked in many fresher interviews):
Does it print long: 10 or Integer: 10? It prints long: 10. This lesson explains exactly why.
Quick Answer
Method overloading in Java means defining several methods with the same name in the same class, each with a different parameter list: a different number, type, or order of parameters. The compiler picks which one to call from the arguments’ types, at compile time. That’s why overloading is called compile-time polymorphism.
Before you start: you should know method signatures from Introduction to Methods and argument matching from Method Parameters.
What Is Method Overloading in Java?
Think of a “Pay” button in a shopping app. You can pay with cash, a UPI ID, or a card. It’s the same action, pay, with different inputs. Overloading lets your code work the same way: one meaningful name, several versions.
Without overloading you’d invent names like areaOfSquare, areaOfRectangle, areaOfCircle. With overloading they’re all area:
Output:
Square: 25Rectangle: 24
Circle: 28.27
The compiler looks at each call’s arguments: one int, two ints, or one double. It wires the call to the matching version.
You already use overloading all the time: System.out.println has versions for int, double, char, String, char[], Object and more.
Rules of Method Overloading in Java
Overloaded methods must have the same name and a different method signature. Remember that the signature is the name plus the parameter types, in order.
Three Valid Ways to Overload a Method
Output:
Jawan: 1 ticketJawan: 3 tickets
Paid Rs 450 in cash
Paid via UPI asha@upi
[200] Seat booked
404 -> Show not found
Overloading by order (way 3) is legal, but it’s easy to call the wrong one by accident. Use it sparingly.
What Does NOT Create an Overload?
| Change only… | Valid overload? | Compiler says |
|---|---|---|
| The return type | ❌ | method discount(int) is already defined |
| The parameter names | ❌ | method area(int,int) is already defined |
static vs non-static | ❌ | method greet(String) is already defined |
Access modifier (public/private) | ❌ | Same signature, so already defined |
throws clause | ❌ | Same signature, so already defined |
The first three were compiled on JDK 25; real messages are in the Common Mistakes section.
Can We Overload a Method by Changing Only the Return Type?
No. The return type isn’t part of the signature, and a call like discount(500); whose result is ignored gives the compiler no way to choose. Two methods that differ only in return type are a compile error.
How Does Java Choose Which Overload to Call?
When several overloads could accept the arguments, the compiler searches in three phases, defined in JLS §15.12.2. It stops at the first phase that finds a match:
Exact matches and widening are tried first, then boxing, and varargs only as a last resort. Within a phase, the compiler picks the most specific method; if there’s a tie, the call is ambiguous.
The Phases in Action
Output:
exact(int)widen(long)
box(long): widening wins
vararg(Integer): boxing wins
onlyVarargs got 1 values
letter(int) got 65
Dry Run
| Call | Phase 1 (exact/widening) | Phase 2 (boxing) | Phase 3 (varargs) | Chosen |
|---|---|---|---|---|
exact(5) | int ✅, long ✅ | — | — | int, the most specific |
widen(5) | long ✅, double ✅ | — | — | long, which is narrower than double |
box(5) | long ✅ | not reached | — | long (the opening puzzle) |
vararg(5) | none | Integer ✅ | not reached | Integer |
onlyVarargs(5) | none | none | int... ✅ | varargs |
letter('A') | int ✅ (char widens) | not reached | — | int, which prints 65 |
Memory hook: Widening beats Boxing beats Varargs. Java 1.4 code already used widening before boxing existed, so the rules prefer it to keep old programs behaving the same.
Most Specific Method
If several overloads match in the same phase, the compiler picks the one whose parameter types are narrowest:
Output:
shortdouble
String
String
text(null) picks String: null fits both, but String is a more specific type than Object. If the two candidates are unrelated (like String and Integer), neither is more specific, and the call is ambiguous (Mistake 4).
Why Is Overloading Called Compile-Time Polymorphism?
The choice is made by the compiler, using the declared (compile-time) types of the arguments, never their runtime types:
Output:
describe(String) got Mumbaidescribe(Object) got MumbaiBoth variables point to the same String object, yet the second call uses describe(Object). The bytecode (javap -c, JDK 25) shows the decision is fixed in the .class file:
6: invokestatic #32 // Method describe:(Ljava/lang/String;)V
10: invokestatic #37 // Method describe:(Ljava/lang/Object;)VAt runtime the JVM simply calls the exact method written in the instruction. That’s static binding: polymorphism resolved at compile time. Its runtime counterpart, overriding, is covered in Introduction to Polymorphism.
Method Overloading vs Method Overriding
| Overloading | Overriding | |
|---|---|---|
| What changes | Parameter list (same name) | Nothing in the signature; the body is replaced |
| Where | Same class (or inherited plus new) | Subclass of the original class |
| Decided | Compile time (static binding) | Runtime (dynamic dispatch) |
| Polymorphism type | Compile-time / static | Runtime / dynamic |
| Return type | Can be anything | Same or a subtype (covariant) |
static / private / final methods | Can be overloaded | Can’t be overridden |
| Needs inheritance | No | Yes |
You’ll study overriding in the Inheritance and Polymorphism sections.
Real-World Pattern: Default Values Through Overloading
Java has no default parameter values. Overloads that delegate to one “full” version give callers short, convenient calls with a single implementation:
Output:
[SMS] Your OTP is 4821[Email] Order shipped
URGENT [WhatsApp] Payment failed
All the real logic lives in one method. Fixing a bug there fixes every overload.
Overloading in the Java Library
Output:
77.5
9
42
true
Java
println(char[]) is its own overload, so it prints the letters instead of an array reference.
Can We Overload the main Method in Java?
Yes. You can declare other methods named main with different parameters. The JVM still starts the program from the standard entry point; the others are ordinary methods you call yourself:
Output:
JVM started main(String[])main(int) called with 5
main(String, int): hellohello(Since Java 25,
void main()is also accepted as an entry point. When a class has both forms, theString[]version is chosen, as shown in Introduction to Methods.)
Can static methods be overloaded? Yes, like any method. Can constructors be overloaded? Yes. Constructor overloading is very common, and you’ll use it in the OOP section (Introduction to OOP).
Common Mistakes With Method Overloading
Mistake 1: Overloading by Return Type Only
ReturnOnly.java:3: error: method discount(int) is already defined in class ReturnOnlystatic double discount(int amount) { return amount * 0.1; }
^
1 error
Fix: change the parameter list, or give the methods different names (discountRupees, discountRate).
Mistake 2: Changing Only Parameter Names or static
NamesOnly.java:3: error: method area(int,int) is already defined in class NamesOnly StaticOnly.java:3: error: method greet(String) is already defined in class StaticOnlyWhy: names and static aren’t part of the signature.
Mistake 3: An Ambiguous Call
Ambiguous.java:6: error: reference to add is ambiguousSystem.out.println(add(5, 5));
^
both method add(int,double) in Ambiguous and method add(double,int) in Ambiguous match
1 error
Why: each overload needs one widening, so neither is more specific.
Mistake 4: Passing null to Unrelated Overloads
NullAmbiguous.java:6: error: reference to print is ambiguousprint(null);
^
both method print(String) in NullAmbiguous and method print(Integer) in NullAmbiguous match
1 error
Mistake 5: Overloads That Mean Different Things
Output:
2.5 kg standard: Rs 100.02.5 kg express: Rs 150.0
4 items: Rs 80.0
4 kg (as 4.0): Rs 160.0
It compiles and runs, but shipping(4) means 4 items while shipping(4.0) means 4 kg, and the costs differ. A caller who types 4 meaning kilograms gets the wrong bill. Fix: overloads must do the same job. Use a different name for a different meaning: shippingForItems(int count).
Mistake 6: Expecting the Runtime Type to Choose the Overload
As CompileTimeType shows, describe(sameCity) calls describe(Object), even though the object is a String. Overload choice uses the declared type.
Best Practices
- Overloads should do the same thing, just with different inputs.
- Delegate: shorter overloads call the most complete one, so the logic lives in one place.
- Avoid overloads that differ only in parameter order (
log(String, int)vslog(int, String)). - Avoid overloads whose types can convert into each other (
intvslong,intvsInteger), since the rules surprise readers. - Be careful mixing overloads with
null, boxing and varargs. Each adds ambiguity risk. - Prefer a clearer name when two “overloads” have different meanings.
- Keep the number of overloads small. Beyond 3–4 versions, consider a parameter object or builder (OOP section).
Interview Questions on Method Overloading
How to answer in an interview: “What is method overloading?”
“Method overloading means having multiple methods with the same name but different parameter lists in the same class. The compiler picks the version from the argument types at compile time, so it’s compile-time polymorphism. Overloads must differ in the number, type or order of parameters. A different return type alone is not enough.”
Output-Prediction Questions
Q1. Overloads m(long) and m(Integer); call m(10).
Answer: m(long). Widening (phase 1) wins over boxing (phase 2).
Q2. Overloads m(Object) and m(String); call m(null).
Answer: m(String), the more specific type. With m(String) and m(Integer) instead, it’s a compile error (ambiguous).
Q3.
Answer: [10, 30]. remove(int index) (exact match) wins over remove(Object), so the element at index 1 is removed, not the value 1. To remove the value 10, call marks.remove(Integer.valueOf(10)), which prints [20, 30]. See ArrayList in Java.
Conceptual Follow-Ups
- Can we overload by return type? No. It’s not part of the signature.
- Can we overload
main? Yes, but the JVM still starts frommain(String[])(or Java 25’svoid main()when noString[]version exists). - Can static and private methods be overloaded? Yes. They can’t be overridden.
- Is overloading resolved at compile time or runtime? Compile time, using declared argument types.
- In what order does Java try conversions? Exact or widening → boxing/unboxing → varargs.
More: Java Interview Questions for Freshers · Intermediate Questions
Practice Exercises
- Easy: Overload
maxfor twoints, threeints, and twodoubles. - Easy: Overload
printReceipt(String item)andprintReceipt(String item, int qty)so the shorter one delegates. - Easy–Medium: Write overloads
convert(int rupees)andconvert(double rupees)that return a formattedString. Predict which runs forconvert('A'). - Medium: Create two overloads that make
calc(2, 3)ambiguous, then fix the call in two different ways. - Medium: Write overloads
describe(Object)anddescribe(String), and show that the declared type decides the call.
Practise on ExamAdda Practice and test in the ExamAdda Compiler.
FAQs
1. What is method overloading in Java?
It’s defining several methods with the same name but different parameter lists in the same class. The compiler chooses the right version from the argument types.
2. Can we overload a method by changing only its return type?
No. The return type isn’t part of the method signature, so the compiler reports “method … is already defined”.
3. Can we overload the main method in Java?
Yes. You can write other main methods with different parameters, but the JVM always starts from the standard entry point. The others must be called explicitly.
4. Why is method overloading called compile-time polymorphism?
Because the compiler decides which overload to call, using the declared types of the arguments. The choice is fixed in the bytecode before the program runs.
5. Which is preferred: widening or autoboxing?
Widening. Java first tries exact matches and widening, then boxing and unboxing, and varargs only last.
6. What causes “reference to method is ambiguous”?
Two or more overloads match equally well and neither is more specific, for example add(int, double) and add(double, int) called with two ints, or null passed to String and Integer versions.
7. Can static methods be overloaded in Java?
Yes. Static, private and final methods can all be overloaded. They just can’t be overridden.
Article Summary
- Overloading means the same method name with a different parameter list (number, type or order); return type, parameter names and
staticdon’t count. - The compiler resolves overloads at compile time in three phases: exact or widening, then boxing, then varargs, and picks the most specific match.
- Overload choice uses the declared types of arguments; ties are compile errors (“reference is ambiguous”).
- Overloading differs from overriding: same class vs subclass, and compile time vs runtime.
- Good overloads do the same job and delegate to one full implementation.
Next → Variable Arguments (Varargs) in Java · ← Previous: Method Return Types
References: JLS §8.4.9: Overloading · JLS §15.12.2: Compile-Time Step 2 (choosing the method) · Oracle Java Tutorials: Defining Methods (Overloading)