OOP

19. Method Overloading

Overloading lets you define multiple methods with the same name but different parameter lists; the compiler selects the best match at compile time via a fixed resolution order: exact match → widening → boxing/unboxing → varargs.

Java 21 (core language)

Explanation

Method overloading is resolved at compile time based on the declared types of the arguments — it is a static (not runtime) decision. The compiler applies a resolution order: exact type match first, then widening conversions (int → long), then boxing/unboxing, then varargs. This order matters when ambiguity arises.

Widening before boxing: print(long) is preferred over print(Long) when called with int. Boxing beats varargs: print(Integer) is preferred over print(int...). Mixing widening and boxing in a single step is not allowed (e.g., int cannot widen to Long in one step).

Overloading does not consider return types — you cannot overload solely by return type. Overloading on null is ambiguous if multiple overloads match reference types; cast null explicitly in such cases.

Example

public class MethodOverloading {
    static void print(int i)     { System.out.println("int:    " + i); }
    static void print(long l)    { System.out.println("long:   " + l); }
    static void print(double d)  { System.out.println("double: " + d); }
    static void print(String s)  { System.out.println("String: " + s); }
    static void print(Object o)  { System.out.println("Object: " + o); }
    static void print(int... vs) { System.out.println("vararg: " + vs.length + " args"); }

    public static void main(String[] args) {
        print(42);       // int (exact match)
        print(42L);      // long (exact match)
        print(42.0);     // double (exact match)
        print("hello");  // String (exact match)

        byte b = 1;
        print(b);        // int (widening: byte -> int)

        // Widening wins over boxing:
        // print(someInt) prefers print(long) over print(Integer)

        // varargs: only chosen if no better match
        print(1, 2, 3);  // vararg: 3 args

        // Null ambiguity
        // print(null); // compile error: ambiguous (String or Object?)
        print((String) null); // explicit cast resolves it -> String: null
    }
}

Sources