Home/Learn/Java A–Z/Methods in Java

Methods in Java

Beginner
Java Fundamentals

Define and call methods, understand pass-by-value semantics, method overloading, varargs, static vs instance, and recursion.

Overview

A method is a named block of code that performs a task and optionally returns a value. Methods are the primary unit of code reuse in Java. Understanding Java's pass-by-value semantics is essential — Java always passes a copy, even for objects (it copies the reference, not the object). Method overloading lets you use the same name for different parameter lists, resolved at compile time. Recursion is powerful but must include a base case to avoid StackOverflowError.

Method Anatomy & Pass-by-Value

A method signature includes: access modifier, optional static/final, return type, name, and parameter list. The method body executes when called.

Java is strictly pass-by-value. For primitives, a copy of the value is passed — the original cannot be changed. For objects, a copy of the reference is passed — you can mutate the object's fields through the reference, but you cannot make the caller's variable point to a different object.

This is one of the most common misconceptions in Java interviews.

PassByValue.java
public class PassByValue {

    static void tryChangeInt(int x) {
        x = 99;  // changes local copy only
    }

    static void tryChangeRef(StringBuilder sb) {
        sb.append(" World");  // mutates the OBJECT — caller sees this
    }

    static void tryReplaceRef(StringBuilder sb) {
        sb = new StringBuilder("Replaced"); // changes LOCAL copy of reference only
    }

    public static void main(String[] args) {
        // Primitive — original unchanged
        int n = 5;
        tryChangeInt(n);
        System.out.println(n);  // 5

        // Object — mutation IS visible (both refs point to same object)
        StringBuilder s = new StringBuilder("Hello");
        tryChangeRef(s);
        System.out.println(s);  // Hello World

        // Reassigning ref inside method — caller NOT affected
        tryReplaceRef(s);
        System.out.println(s);  // Hello World (unchanged)
    }
}

Method Overloading & Varargs

Method overloading lets you define multiple methods with the same name but different parameter lists (different types, number, or order of parameters). The compiler picks the correct version at compile time based on the argument types — this is called static polymorphism.

Varargs (variable-length arguments) let a method accept any number of arguments of a given type. Internally, Java wraps them in an array. Rules: only one varargs per method, and it must be the last parameter.

OverloadVarargs.java
public class OverloadVarargs {

    // Overloaded methods — different parameter types
    static int add(int a, int b)       { return a + b; }
    static double add(double a, double b) { return a + b; }
    static int add(int a, int b, int c) { return a + b + c; }

    // Varargs — accepts 0 or more ints
    static int sum(int... numbers) {
        int total = 0;
        for (int n : numbers) total += n;
        return total;
    }

    // Mixing regular params + varargs (varargs must be last)
    static String format(String label, Object... values) {
        StringBuilder sb = new StringBuilder(label).append(": ");
        for (Object v : values) sb.append(v).append(" ");
        return sb.toString().trim();
    }

    public static void main(String[] args) {
        System.out.println(add(2, 3));        // 5  — int version
        System.out.println(add(2.0, 3.0));    // 5.0 — double version
        System.out.println(add(1, 2, 3));     // 6  — 3-arg version

        System.out.println(sum());            // 0
        System.out.println(sum(1, 2, 3, 4)); // 10
        System.out.println(sum(new int[]{5, 10, 15})); // 30 — array works too

        System.out.println(format("Scores", 90, 85, 92));
        // Scores: 90 85 92
    }
}

Recursion & the Call Stack

A recursive method calls itself. Every recursive solution needs: 1. A base case — when to stop recursing 2. A recursive case — the call that moves toward the base case

Each method call creates a new stack frame on the JVM stack. Too many recursive calls without returning causes a StackOverflowError. For large inputs, prefer iteration or use tail-recursion with a helper. Java does NOT perform tail-call optimisation (unlike some functional languages).

Recursion.java
public class Recursion {

    // Factorial — classic recursion
    static long factorial(int n) {
        if (n <= 1) return 1;           // base case
        return n * factorial(n - 1);    // recursive case
    }

    // Fibonacci — naive O(2^n); memoize for real use
    static long fib(int n) {
        if (n <= 1) return n;
        return fib(n - 1) + fib(n - 2);
    }

    // Binary search — recursive
    static int binarySearch(int[] arr, int target, int lo, int hi) {
        if (lo > hi) return -1;         // base case: not found
        int mid = lo + (hi - lo) / 2;  // avoids overflow vs (lo+hi)/2
        if (arr[mid] == target) return mid;
        if (arr[mid] < target) return binarySearch(arr, target, mid + 1, hi);
        return binarySearch(arr, target, lo, mid - 1);
    }

    // Iterative equivalent — preferred for large n
    static long factorialIterative(int n) {
        long result = 1;
        for (int i = 2; i <= n; i++) result *= i;
        return result;
    }

    public static void main(String[] args) {
        System.out.println(factorial(10));   // 3628800
        System.out.println(fib(10));         // 55

        int[] sorted = {2, 5, 8, 12, 16, 23};
        System.out.println(binarySearch(sorted, 12, 0, sorted.length - 1)); // 3
    }
}

Key Points to Remember

  • Java is strictly pass-by-value — for objects, the reference is copied, not the object
  • Method overloading is resolved at compile time (static polymorphism); overriding is runtime
  • Varargs (int... nums) must be the last parameter; internally treated as an array
  • Every recursive call consumes a stack frame — deep recursion without a base case causes StackOverflowError
  • Java does not optimise tail recursion — for large inputs, prefer iterative solutions
  • Use lo + (hi - lo) / 2 instead of (lo + hi) / 2 in binary search to avoid integer overflow

Practice Methods in Java in the Playground

Run and modify code directly in your browser - no setup needed.

Interview Questions

Sign in to ask Aria
1

Is Java pass-by-value or pass-by-reference? Explain with an example.

MediumGoogle
2

What is method overloading? How does the compiler choose the right method?

EasyAmazon
3

What is the difference between method overloading and method overriding?

EasyTCS
4

What causes a StackOverflowError? How do you fix it?

MediumMicrosoft
5

Write a recursive method to compute the nth Fibonacci number

EasyFacebook

Ask Aria about Methods in Java

Your personal AI tutor — ask anything about this concept