All topics
library
beginner

Method Overloading Rules

Know the exact rules Java uses to resolve overloaded methods and the common pitfalls with autoboxing and varargs.

When several methods share a name, the compiler picks one in a fixed order and stops at the first that fits.

Mail sorting: exact zip code slot first, then regional bin, then state bin, then everything-else bin. Most specific match wins.

Key Concepts

1
    1. exact match            f(int) for f(5)
    2. widening primitive     int -> long -> float -> double
    3. autoboxing             int -> Integer
    4. varargs               String... matches anything
2
Earlier phases win outright. Widening beats boxing, and boxing beats varargs:
3
    void f(long x)     { print("long"); }
    void f(Integer x)  { print("Integer"); }
    void f(int... x)   { print("varargs"); }
4
    f(5);              // "long" -- widening, phase 2
5
That surprises people who expect Integer to win because 5 is an int. Boxing is phase 3, and phase 2 already matched.
Integer5int
6
Within a phase, the most specific method wins.
    void g(Object o) { print("Object"); }
    void g(String s) { print("String"); }
7
    g(null);           // "String" -- String is more specific
8
And adding a sibling can break it.
    void g(Integer i) { ... }      // now also applicable to null
9
    g(null);           // compile error: ambiguous
10
String and Integer are both applicable and neither is more specific, so there is no best match.
StringInteger
11
The reference type decides, not the object.
    Object o = "hello";
    g(o);              // "Object" -- the compiler only sees Object
12
Return type alone is not an overload.
    int  h(String s) { ... }
    long h(String s) { ... }        // will not compile
13
And a practical warning. Overloading on types a caller might confuse — remove(int) versus remove(Object) on List — causes real bugs. list.remove(1) removes the index, not the value.
remove(int)remove(Object)Listlist.remove(1)
14
What the interviewer is probing.1. "Given f(long) and f(Integer), what does f(5) call?" Probing: the resolution phases. Stalls: "f(Integer), because 5 is an int." Moves up: f(long) — widening is phase two and boxing is phase three, so widening wins before boxing is considered.
15
2. "Why does adding an overload sometimes break code that compiled before?" Probing: ambiguity. Stalls: "It should not." Moves up: with f(String) and f(Integer), the call f(null) becomes ambiguous because neither is more specific, so an existing call stops compiling.
16
3. "list.remove(1) on a List<Integer> — what does it remove?" Probing: whether you have hit the classic overloading trap. Stalls: "The value 1." Moves up: the element at index 1, because remove(int) is an exact match and remove(Object) would need boxing. Use remove(Integer.valueOf(1)) for the value.
17
4. "Can two methods differing only in return type be overloads?" Probing: what counts as a signature. Stalls: "Yes, the types differ." Moves up: no — the signature is the name and parameter list, so it does not compile.