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

▶ Try it in the ExamAdda Compiler

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

▶ Try it in the ExamAdda Compiler

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

▶ Try it in the ExamAdda Compiler

Dry Run
CallPhase 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)noneInteger ✅not reachedInteger
onlyVarargs(5)nonenoneint... ✅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 Mumbai

▶ Try it in the ExamAdda Compiler

Both 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:

text
         6: invokestatic  #32                 // Method describe:(Ljava/lang/String;)V
        10: invokestatic  #37                 // Method describe:(Ljava/lang/Object;)V

At 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

OverloadingOverriding
What changesParameter list (same name)Nothing in the signature; the body is replaced
WhereSame class (or inherited plus new)Subclass of the original class
DecidedCompile time (static binding)Runtime (dynamic dispatch)
Polymorphism typeCompile-time / staticRuntime / dynamic
Return typeCan be anythingSame or a subtype (covariant)
static / private / final methodsCan be overloadedCan’t be overridden
Needs inheritanceNoYes

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

▶ Try it in the ExamAdda Compiler

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, the String[] 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 ReturnOnly    static 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 StaticOnly

Why: names and static aren’t part of the signature.

Mistake 3: An Ambiguous Call

Ambiguous.java:6: error: reference to add is ambiguous        System.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 ambiguous        print(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

  1. Overloads should do the same thing, just with different inputs.
  2. Delegate: shorter overloads call the most complete one, so the logic lives in one place.
  3. Avoid overloads that differ only in parameter order (log(String, int) vs log(int, String)).
  4. Avoid overloads whose types can convert into each other (int vs long, int vs Integer), since the rules surprise readers.
  5. Be careful mixing overloads with null, boxing and varargs. Each adds ambiguity risk.
  6. Prefer a clearer name when two “overloads” have different meanings.
  7. 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

  1. Can we overload by return type? No. It’s not part of the signature.
  2. Can we overload main? Yes, but the JVM still starts from main(String[]) (or Java 25’s void main() when no String[] version exists).
  3. Can static and private methods be overloaded? Yes. They can’t be overridden.
  4. Is overloading resolved at compile time or runtime? Compile time, using declared argument types.
  5. In what order does Java try conversions? Exact or widening → boxing/unboxing → varargs.

More: Java Interview Questions for Freshers · Intermediate Questions

Practice Exercises

  1. Easy: Overload max for two ints, three ints, and two doubles.
  2. Easy: Overload printReceipt(String item) and printReceipt(String item, int qty) so the shorter one delegates.
  3. Easy–Medium: Write overloads convert(int rupees) and convert(double rupees) that return a formatted String. Predict which runs for convert('A').
  4. Medium: Create two overloads that make calc(2, 3) ambiguous, then fix the call in two different ways.
  5. Medium: Write overloads describe(Object) and describe(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 static don’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)