What you'll learn

  • How to define and call a method
  • Parameters, return values and void
  • Overloading and varargs
  • Recursion, and how Java passes arguments

As programs grow, you’ll find yourself writing the same few lines again and again. A method gives those lines a name so you can reuse them, test them and change them in one place.

Anatomy of a method

static double lineTotal(int quantity, double price) {
    return quantity * price;
}
  • static — belongs to the class itself (more on that in Classes and objects). For now, methods called from main are static.
  • double — the return type: what the method gives back. Use void if it returns nothing.
  • lineTotal — the name, in camelCase, usually a verb or a noun describing the result.
  • (int quantity, double price) — the parameters: inputs, each with a type.
  • return — hands the result back and ends the method.

Call it with matching arguments:

double total = lineTotal(24, 8.50);   // 204.0

Methods that return nothing

static void printReceipt(String customer, double amount) {
    System.out.printf("%-12s %8.2f%n", customer, amount);
}

Overloading: same name, different inputs

static double lineTotal(int quantity, double price, double discountPercent) {
    double total = lineTotal(quantity, price);       // reuse the simpler version
    return total - total * discountPercent / 100;
}

Java picks the right version by the number and types of arguments.

Varargs: any number of arguments

static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) total += n;
    return total;
}
sum(1, 2, 3, 4);   // 10

Inside the method, numbers is simply an array.

Recursion: a method that calls itself

static long factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

Every recursive method needs a base case (n <= 1) that stops the calls, or it will run until the stack overflows.

How arguments are passed

Java always passes a copy of the value. For primitives, changing the parameter inside the method doesn’t affect the caller’s variable. For objects, the copy is a copy of the reference — so the method can change the object’s contents (add to a list, for example), but can’t make the caller’s variable point to a different object.

Good method habits

  • One method, one job. If you need “and” to describe it, consider splitting it.
  • Name it after what it returns or does: calculateTax, isValidSku, sendInvoice.
  • Keep parameter lists short; if you need many, group them into an object (or a record).

The full example

// Methods.java — defining, calling and overloading methods.
public class Methods {

    // A method with parameters and a return value
    static double lineTotal(int quantity, double price) {
        return quantity * price;
    }

    // Overloading: same name, different parameters
    static double lineTotal(int quantity, double price, double discountPercent) {
        double total = lineTotal(quantity, price);
        return total - total * discountPercent / 100;
    }

    // A method that returns nothing (void)
    static void printReceipt(String customer, double amount) {
        System.out.printf("%-12s %8.2f%n", customer, amount);
    }

    // Varargs: accept any number of arguments
    static int sum(int... numbers) {
        int total = 0;
        for (int n : numbers) {
            total += n;
        }
        return total;
    }

    // Recursion: a method that calls itself
    static long factorial(int n) {
        return n <= 1 ? 1 : n * factorial(n - 1);
    }

    public static void main(String[] args) {
        printReceipt("Acme Ltd", lineTotal(24, 8.50));
        printReceipt("Globex", lineTotal(10, 20.00, 15));
        System.out.println("Sum: " + sum(1, 2, 3, 4));
        System.out.println("5! = " + factorial(5));
    }
}

Try it yourself

Write a method isValidSku(String sku) that returns true when the text is two capital letters, a dash and three digits (like AX-200). Hint: String has a matches(regex) method.

Show a solution
static boolean isValidSku(String sku) {
    return sku != null && sku.matches("[A-Z]{2}-\\d{3}");
}
// isValidSku("AX-200") -> true, isValidSku("ax-2") -> false

In a Java string, the regex \d (a digit) is written \\d.

Key takeaways

  • A method has a return type, a name, parameters and a body; return sends a value back.
  • Overloading lets several methods share a name; varargs accept any number of arguments.
  • Recursion needs a base case.
  • Java passes copies of values — for objects, a copy of the reference.

Example files