Notifications

No notifications

/Phase 2

Methods & Overloading

Methods — Java's Functions ⚙️

In Java, every method lives inside a class. Unlike Python or JavaScript, you can't define a free-standing function. The signature is:

[modifiers] returnType name(paramType paramName, ...) {
    // body
    return value;
}

public class MathUtil {
    // a static method — call without an instance
    public static int square(int x) {
        return x * x;
    }

// an instance method — needs new MathUtil() public double cube(double x) { return x * x * x; } }

// usage int s = MathUtil.square(5); // 25 double c = new MathUtil().cube(2.5); // 15.625

Overloading — Same Name, Different Signature

public static int    max(int a, int b)        { return a > b ? a : b; }
public static double max(double a, double b)  { return a > b ? a : b; }
public static int    max(int a, int b, int c) { return max(max(a, b), c); }

The compiler picks the right one by argument types and count. Return type alone is NOT enough to overload.

Varargs

public static int sum(int... nums) {
    int total = 0;
    for (int n : nums) total += n;
    return total;
}

sum(); // 0 sum(1, 2, 3); // 6 sum(new int[]{1,2}); // 3

Recursion

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

On this page

Detailed Theory

Method Anatomy

public static int add(int a, int b) {
    return a + b;
}
//  ^      ^   ^   ^   ^      ^      ^
//        └ method body
//        └ parameter list
//     └ method name
//     └ return type (use void for no return)
//     └ "static" — belongs to the class, not an instance
//  |      └ access modifier
//  └ optional access scope

Access Modifiers

ModifierVisibility
publiceveryone
protectedsame package + subclasses
(none / package-private)same package
privatesame class only

static vs Instance

staticinstance
Belongs tothe classeach object
Call asMath.sqrt(2)obj.sqrt(2)
Has this?NoYes
Common useutility functions, factory methodsobject behaviour

public class Counter {
    static int totalCounters = 0;   // shared across all instances
    int count;                       // per-instance

public Counter() { totalCounters++; } public void inc() { count++; } public int get() { return count; } public static int howMany() { return totalCounters; } }

Parameters — Pass-by-Value (Always)

Java has only pass-by-value. But for reference types, the *value being passed* IS a reference (a pointer to the object). So:

static void reassign(int[] arr) {
    arr = new int[]{99};   // local variable now points elsewhere
}
static void mutate(int[] arr) {
    arr[0] = 99;           // modifies the SAME array the caller has
}

public static void main(String[] a) { int[] x = {1, 2, 3}; reassign(x); System.out.println(x[0]); // 1 (caller's reference unchanged) mutate(x); System.out.println(x[0]); // 99 (caller's array WAS mutated) }

> Rule of thumb: you can't change what the caller's variable POINTS to, but you can mutate the object behind that reference.

Overloading

Multiple methods with the same name but different parameter lists:

public class Printer {
    public static void show(int x)        { System.out.println("int " + x); }
    public static void show(double x)     { System.out.println("double " + x); }
    public static void show(String x)     { System.out.println("string " + x); }
    public static void show(int x, int y) { System.out.println("two ints " + x + ", " + y); }
}

Resolution rules (the compiler picks the best fit):

1. Exact match wins (show(5)int overload). 2. Then widening primitives (int → long → double). 3. Then autoboxing (int → Integer). 4. Then varargs.

> Return type alone CANNOT distinguish overloads — the compiler refuses.

Varargs (Variable Arguments)

public static String join(String sep, String... parts) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < parts.length; i++) {
        if (i > 0) sb.append(sep);
        sb.append(parts[i]);
    }
    return sb.toString();
}

join(", ", "a", "b", "c"); // "a, b, c"

Rules:

  • The varargs parameter must be last.
  • Inside the method it's just an array (String[]).
  • You can pass an actual array.

Default Parameters? Use Overloading

Java has no default parameters. The idiomatic substitute is overloading:

public static String greet(String name)            { return greet(name, "Hello"); }
public static String greet(String name, String hi) { return hi + ", " + name + "!"; }

greet("Asha"); // "Hello, Asha!" greet("Asha", "Welcome"); // "Welcome, Asha!"

Recursion

public static int fib(int n) {
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);     // O(2^n) — slow
}

For deep recursion, use memoisation or convert to iteration. The default JVM stack is ~512 KB → roughly 10⁴ frames before StackOverflowError.

return and void

  • A non-void method must return on every code path.
  • void methods can use return; (no value) to exit early.
public static int abs(int n) {
    if (n < 0) return -n;
    return n;       // every path covered
}

public static void greet(String name) { if (name == null) return; System.out.println("Hi " + name); }

Method References (Quick Preview)

Once you know lambdas, you can pass methods as values:

import java.util.function.*;

Function<Integer, Integer> sq = MathUtil::square; sq.apply(5); // 25

Full coverage in the lambdas topic.

Naming & Style

  • camelCase: computeTotal, getUserById.
  • Verbs for actions: save, delete, render.
  • Booleans as isXxx / hasXxx: isEmpty(), hasNext().
  • Keep methods small — under ~30 lines is a good guideline.

Common Mistakes

BugFix
Forgot return on a code pathCompiler tells you — fix the missing branch
Tried to overload by return type onlyAdd a parameter difference
Mutating a parameter and expecting caller to see reassignmentJava is pass-by-value; return the new value
Calling instance method without an objectAdd static or instantiate (new MyClass().foo())
Recursive call without base caseAdd a termination condition

Cheat-Sheet

NeedCode
Define static methodstatic int f(int x) { ... }
Call static methodClassName.method(args)
Variable argsint sum(int... ns)
OverloadSame name, different params
Pass array as varargssum(new int[]{1,2,3})
Early exit (void)return;
Recursion limit~10⁴ frames before StackOverflow

You can now organise code into reusable methods. Next: strings — Java's most-used object.