Java Methods and Recursion Explained Simply

Updated on October 22, 2026

Methods in Java give a piece of code a name. You call a method as often as you like and only have to write the code once. In this article you write your own methods, overload them and let them call themselves.

Your own methods

A method sits in the class next to main, not inside it. Its header has four parts:

public static double grossPrice(double net)
  1. public static: always goes in front for now. What it means is explained in the article on classes and objects in Java.
  2. Return type: double, int, boolean, String, … or void if the method returns nothing.
  3. Name: lower case, says what the method does.
  4. Parameters: in parentheses, each with a type, separated by commas. When the method is called, they get the values you pass.

return hands back the result and ends the method immediately. You can store the return value, print it or keep calculating with it.

public class Main {    public static double grossPrice(double net) {        return net * 1.19;    }
    public static boolean isAdult(int age) {        return age >= 18;    }
    public static void printLine(int length) {        for (int i = 0; i < length; i++) {            System.out.print("-");        }        System.out.println();    }
    public static void main(String[] args) {        printLine(20);        System.out.printf("Gross: %.2f%n", grossPrice(50.0));        double total = grossPrice(10.0) + grossPrice(20.0);        System.out.printf("Total: %.2f%n", total);        System.out.println("Adult at 17? " + isAdult(17));        printLine(20);    }}

Overloading and varargs

Several methods may have the same name if their parameters differ, in number or type. This is called overloading. When you call it, Java picks the matching one by the arguments. One method may call another, just as max with three parameters uses the one with two.

If a method should take any number of values, put three dots after the type: int... numbers. This is called varargs. Inside the method, numbers is a normal array, an empty one if you pass nothing.

public class Main {    public static int max(int a, int b) {        if (a > b) {            return a;        }        return b;    }
    public static int max(int a, int b, int c) {        return max(max(a, b), c);    }
    public static int sum(int... numbers) {        int total = 0;        for (int n : numbers) {            total += n;        }        return total;    }
    public static void main(String[] args) {        System.out.println(max(3, 7));        System.out.println(max(3, 9, 5));        System.out.println(sum());        System.out.println(sum(4));        System.out.println(sum(1, 2, 3, 4));    }}

Recursion

A method may call itself. This is called recursion and fits when a problem can be reduced to a smaller version of the same problem. Every recursion needs two parts:

  • a base case that knows the result directly, e.g. factorial(1) is 1,
  • a recursive call with a smaller value, e.g. n * factorial(n - 1).

This is how Java calculates factorial(3): 3 * factorial(2) → 3 * 2 * factorial(1) → 3 * 2 * 1 = 6. You'll find bigger examples in the article on recursion and backtracking.

public class Main {    public static void countdown(int n) {        if (n == 0) {            System.out.println("Go!");            return;        }        System.out.println(n);        countdown(n - 1);    }
    public static int factorial(int n) {        if (n <= 1) {            return 1;        }        return n * factorial(n - 1);    }
    public static void main(String[] args) {        countdown(3);        for (int i = 1; i <= 5; i++) {            System.out.println(i + "! = " + factorial(i));        }    }}

Common mistakes

  • Method written inside main

    A method can't be inside another one. If it's between the braces of main, the compiler reports illegal start of expression. Methods sit side by side in the class.

  • return missing in one branch

    If a method has a return type, every path through it must end with return:

    public static String sign(int n) {    if (n > 0) {        return "positive";    } else if (n < 0) {        return "negative";    }    // missing return statement}

    A return "zero"; at the end fixes the error.

  • Return value thrown away

    grossPrice(10.0); on its own does calculate, but the result is lost. Store it (double price = grossPrice(10.0);) or print it. The other way round, a method doesn't print anything just because it has a return.

  • Parameters are copies

    For int, double and boolean, the method gets a copy of the value. If it changes the parameter, the caller doesn't notice. For arrays, however, it gets a reference to the same array (see arrays in Java): changes to the elements are visible outside afterwards.

  • Recursion without a stop

    If the base case is missing or never reached, the method keeps calling itself until the program stops with StackOverflowError. Check: does the value get smaller with every call, and does it surely reach the base case?

Tasks on this topic

Practise what you learned right in your browser. Tests check your solution instantly.