Skip to content
Laviyx Learn

Try

Java course menu

Java Method Overloading: Same Name, Different Parameters

Learn method overloading in Java: several methods with the same name and different parameter lists, how the compiler chooses an overload, widening and autoboxing in overload resolution, ambiguous calls, and simulating default arguments.

Beginner8 min readUpdated
On this page

Overloading means defining several methods with the same name but different parameter lists in the same class. It lets one natural name cover different kinds of input, just as System.out.println prints an int, a double or a String.

Overloading by parameter type#

Java
public class Main {
    static void print(int value) {
        System.out.println("int: " + value);
    }

    static void print(double value) {
        System.out.println("double: " + value);
    }

    static void print(String value) {
        System.out.println("String: " + value);
    }

    public static void main(String[] args) {
        print(42);
        print(3.5);
        print("hello");
    }
}
Output
int: 42
double: 3.5
String: hello

The compiler chooses the overload from the argument types, at compile time.

Overloading by number of parameters#

Java
public class Main {
    static int area(int side) {
        return side * side;
    }

    static int area(int width, int height) {
        return width * height;
    }

    public static void main(String[] args) {
        System.out.println(area(5) + " " + area(4, 6));
    }
}
Output
25 24

What does not count as an overload#

Overloads must differ in parameter types, number or order. A different return type alone, or different parameter names, is not enough:

Java
public class Main {
    static int parse(String text) { return 0; }
    static double parse(String text) { return 0; }   // error: already defined
}

How the compiler picks: exact match, widening, boxing#

When there is no exact match, Java tries, in order:

  1. Widening a primitive (int to long or double);
  2. Autoboxing (int to Integer);
  3. Varargs.
Java
public class Main {
    static void show(long x) { System.out.println("long " + x); }
    static void show(Integer x) { System.out.println("Integer " + x); }
    static void show(int... xs) { System.out.println("varargs " + xs.length); }

    public static void main(String[] args) {
        show(5);        // int: widening to long wins over boxing and varargs
        show(5, 6);     // only varargs fits
    }
}
Output
long 5
varargs 2

Knowing this order explains surprising choices, but well-designed overloads avoid relying on it.

Ambiguous calls#

If two overloads match equally well, the call is rejected:

Java
public class Main {
    static void send(Integer id, String note) { }
    static void send(String note, Integer id) { }

    public static void main(String[] args) {
        send(null, null);   // error: reference to send is ambiguous
    }
}

Default arguments: overloading instead#

Java has no default parameter values. The usual replacement is an overload that supplies the default and calls the full version:

Java
public class Main {
    static String greet(String name, String greeting, int times) {
        return (greeting + ", " + name + "! ").repeat(times).trim();
    }

    static String greet(String name, String greeting) {
        return greet(name, greeting, 1);
    }

    static String greet(String name) {
        return greet(name, "Hello");
    }

    public static void main(String[] args) {
        System.out.println(greet("Asha"));
        System.out.println(greet("Ravi", "Welcome"));
        System.out.println(greet("Meera", "Hi", 2));
    }
}
Output
Hello, Asha!
Welcome, Ravi!
Hi, Meera! Hi, Meera!

Each shorter overload delegates to a longer one, so the real logic exists in only one place. When there are many optional settings, the builder pattern is a better tool.

Overloading vs overriding#

Do not confuse the two:

OverloadingOverriding
WhereSame class (or a subclass)A subclass replaces an inherited method
SignatureDifferent parameter listSame signature
ChosenAt compile time, from argument typesAt run time, from the object's actual class

Overriding is covered in Inheritance and Polymorphism.

Common mistakes#

Practice#

Practice exercise

Write three overloads of maxOf: for two ints, for three ints (reusing the first), and for two doubles. Print maxOf(3, 9), maxOf(4, 12, 7) and maxOf(2.5, 1.5).

Show solution
Java
public class MaxOf {
    static int maxOf(int a, int b) {
        return a > b ? a : b;
    }

    static int maxOf(int a, int b, int c) {
        return maxOf(maxOf(a, b), c);
    }

    static double maxOf(double a, double b) {
        return a > b ? a : b;
    }

    public static void main(String[] args) {
        System.out.println(maxOf(3, 9) + " " + maxOf(4, 12, 7) + " " + maxOf(2.5, 1.5));
    }
}
Output
9 12 2.5

In real code, Math.max already provides these overloads.

Key takeaway#

Finished this lesson?