Methods

Reviewed & published by Brayan K

Right now, all your code lives inside main(). That works for small programs, but imagine a 500-line main() method — impossible to read, debug, or reuse! Methods let you split your code into small, named, reusable pieces. Think of them like recipe cards: each method does one thing, and you call it by name whenever you need it.

Part of the free Java course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn

💡 Real-World Analogy: Recipe Cards

A method is like a recipe card. It has a name ("Chocolate Cake"), ingredients (parameters — flour, sugar, eggs), instructions (the method body), and a result (return value — a finished cake). You write the recipe once, and you can follow it any time without memorizing the steps — just call the recipe by name.

1️⃣ Creating Your First Method

Every method has a specific structure. Let's break it down piece by piece:

// Method anatomy:
// [access] [static] returnType methodName(parameters) {
//     // body — the code that runs
//     return value;  // (if not void)
// }

public static void sayHello() {
    System.out.println("Hello, World!");
}

// Let's break each part down:
// public  → Who can use this method (anyone)
// static  → Can be called without creating an object
// void    → This method doesn't return a value
// sayHello → The name (use a verb!)
// ()      → No parameters needed

To call (use) this method:

public static void main(String[] args) {
    sayHello();   // Prints: Hello, World!
    sayHello();   // Prints it again — reusable!
    sayHello();   // And again!
}

🔑 Key insight: You define a method once (write the recipe), then call it as many times as you want (follow the recipe). The code inside the method only runs when you call it — defining it doesn't execute it.

2️⃣ Parameters — Passing Data Into Methods

Most methods need some data to work with. Parameters are variables listed in the method definition that receive values when the method is called. The values you pass in are called arguments.

// One parameter
public static void greet(String name) {
    System.out.println("Hello, " + name + "!");
}

greet("Alice");    // Hello, Alice!
greet("Bob");      // Hello, Bob!

// Multiple parameters
public static void printSum(int a, int b) {
    System.out.println(a + " + " + b + " = " + (a + b));
}

printSum(5, 3);    // 5 + 3 = 8
printSum(10, 20);  // 10 + 20 = 30

Think of it like a form: the parameter is the blank field label ("Name: ___"), and the argument is what you fill in ("Alice").

3️⃣ Return Values — Getting Results Back

A void method does something but doesn't give you anything back (like printing). A return method computes a value and hands it back to whoever called it. You can then store that value, print it, or use it in another calculation.

void — "Do something"

void greet(String name) {
    System.out.println("Hi, " + name);
    // No return needed
}

greet("Alice");
// Can't store the result:
// String x = greet("Alice"); ❌

Return — "Give me something"

int add(int a, int b) {
    return a + b;
}

// Store and use the result:
int result = add(5, 3);   // 8
int total = add(10, add(2, 3));
// add(2,3) returns 5
// add(10, 5) returns 15
// More return examples:
public static double calculateTax(double price, double rate) {
    return price * rate;
}

public static boolean isEven(int number) {
    return number % 2 == 0;
}

public static String getGrade(int score) {
    if (score >= 90) return "A";
    if (score >= 80) return "B";
    if (score >= 70) return "C";
    return "F";
}

// Using them:
double tax = calculateTax(100.0, 0.08);  // 8.0
boolean even = isEven(7);                 // false
String grade = getGrade(85);              // "B"
public class Main {
    // 1. Void method (no return value)
    static void greet(String name) {
        System.out.println("   Hello, " + name + "!");
    }

    // 2. Methods that return a value
    static int add(int a, int b) { return a + b; }
    static int multiply(int a, int b) { return a * b; }

    // 4. Method with branching logic
    static String getGrade(int score) {
        if (score >= 90) return "A";
        if (score >= 80) return "B";
        if (score >= 70) return "C";
        if (score >= 60) return "D";
        return "F";
    }

    // 5. Boolean-returning methods
    static boolean isEven(int n) { return n % 2 == 0; }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) return false;
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println("=== Creating & Calling Methods ===\n");

        System.out.println("1. VOID METHODS:");
        greet("Alice");
        greet("Bob");
        greet("Charlie");

        System.out.println("\n2. RETURN METHODS:");
        System.out.println("   add(5, 3) = " + add(5, 3));
        System.out.println("   multiply(4, 7) = " + multiply(4, 7));

        System.out.println("\n3. CHAINING METHODS:");
        System.out.println("   add(multiply(3, 4), 5) = " + add(multiply(3, 4), 5));

        System.out.println("\n4. METHODS WITH LOGIC (Grade Calculator):");
        int[] scores = {95, 82, 73, 61, 45};
        for (int s : scores) {
            System.out.println("   Score " + s + " -> " + getGrade(s));
        }

        System.out.println("\n5. BOOLEAN METHODS:");
        System.out.println("   isEven(8) = " + isEven(8));
        System.out.println("   isEven(7) = " + isEven(7));
        System.out.println("   isPrime(17) = " + isPrime(17));
        System.out.println("   isPrime(15) = " + isPrime(15));
    }
}

4️⃣ Method Overloading — Same Name, Different Parameters

Java allows you to have multiple methods with the same name, as long as they have different parameter lists. The compiler picks the right version based on the arguments you pass. This is called overloading.

// Three "add" methods — different parameter types/counts
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;
}

// Java picks the right one automatically:
add(5, 3);          // → calls int version → 8
add(5.5, 3.2);      // → calls double version → 8.7
add(1, 2, 3);       // → calls 3-parameter version → 6

Real-world example: System.out.println() is overloaded! It can print a String, int, double, boolean, char — there are actually 10+ versions of println(), and Java picks the right one based on what you pass.

⚠️ You CANNOT overload by return type alone:

int  calculate(int x) { ... }
double calculate(int x) { ... }  // ❌ Won't compile!
// Same name AND same parameters — Java can't tell them apart

5️⃣ Pass-by-Value — How Java Handles Arguments

This concept confuses many beginners, so pay close attention. Java is always pass-by-value. This means when you pass a variable to a method, the method gets a copy of the value, not the original variable. Changes inside the method don't affect the original.

static void tryToDouble(int x) {
    x = x * 2;  // Changes the COPY, not the original
    System.out.println("Inside method: x = " + x);  // 20
}

public static void main(String[] args) {
    int num = 10;
    tryToDouble(num);
    System.out.println("After method: num = " + num);  // Still 10!
}

// The method got a copy of 10, doubled it to 20 internally,
// but the original 'num' variable was never touched.

🔑 The workaround: If you need a method to produce a new value, use return:

static int doubleIt(int x) {
    return x * 2;
}
int num = 10;
num = doubleIt(num);  // Now num is 20!

6️⃣ Variable Scope — Where Variables Live

Variables declared inside a method are local to that method — they don't exist outside it. This is called scope. Each method is like its own room: you can't see what's inside another room.

static void methodA() {
    int x = 10;  // x only exists in methodA
    System.out.println(x);  // ✅ Works
}

static void methodB() {
    System.out.println(x);  // ❌ ERROR! x doesn't exist here
}

// Parameters are also local:
static void greet(String name) {
    // 'name' only exists inside greet()
}
// Can't use 'name' out here!

💡 This is a feature, not a bug! Scope prevents methods from accidentally interfering with each other. You can use the same variable name (result, i, temp) in different methods without any conflict.

public class Main {
    // Method overloading: same name, different parameter lists
    static double area(double radius) {        // circle
        return Math.PI * radius * radius;
    }
    static double area(double width, double height) {  // rectangle
        return width * height;
    }

    // Pass-by-value: the method gets a COPY of the argument
    static int tryToDouble(int x) {
        x = x * 2;
        System.out.println("   Inside method: x = " + x);
        return x;
    }

    static double celsiusToFahrenheit(double c) { return (c * 9 / 5) + 32; }
    static double fahrenheitToCelsius(double f) { return (f - 32) * 5 / 9; }
    static double kmToMiles(double km) { return km * 0.621371; }

    // Methods calling other methods
    static double square(double n) { return n * n; }
    static double distance(double x1, double y1, double x2, double y2) {
        return Math.sqrt(square(x2 - x1) + square(y2 - y1));
    }

    public static void main(String[] args) {
        System.out.println("=== Overloading & Pass-by-Value ===\n");

        System.out.println("1. METHOD OVERLOADING:");
        System.out.printf("   area(5) -> Circle: %.2f%n", area(5));
        System.out.printf("   area(10, 5) -> Rectangle: %.2f%n", area(10, 5));

        System.out.println("\n2. PASS-BY-VALUE:");
        int original = 10;
        tryToDouble(original);
        System.out.println("   After method: original = " + original + " (unchanged!)");
        original = tryToDouble(original);
        System.out.println("   Now original = " + original);

        System.out.println("\n3. UNIT CONVERTER:");
        System.out.printf("   100C = %.1fF%n", celsiusToFahrenheit(100));
        System.out.printf("   72F = %.1fC%n", fahrenheitToCelsius(72));
        System.out.printf("   42km = %.1f miles%n", kmToMiles(42));

        System.out.println("\n4. METHODS CALLING METHODS:");
        System.out.printf("   distance(0,0 -> 3,4) = %.1f%n", distance(0, 0, 3, 4));
        System.out.printf("   distance(1,1 -> 4,5) = %.2f%n", distance(1, 1, 4, 5));
    }
}

7️⃣ Static vs Instance Methods (Preview)

You've been using static methods so far because they work without creating objects. Once you learn OOP in the Object-Oriented Programming lesson, you'll use instance methods too. Here's a quick preview:

Static Method

Call directly on the class. No object needed.

Math.max(5, 10);       // 10
Math.sqrt(16);         // 4.0
Integer.parseInt("42"); // 42

Instance Method

Must create an object first.

String name = "Hello";
name.length();         // 5
name.toUpperCase();    // "HELLO"
name.charAt(0);        // 'H'

For now, keep using static for all your methods. You'll understand the difference deeply in the OOP lesson.

public class Main {
    static int add(int a, int b) { return a + b; }
    static int subtract(int a, int b) { return a - b; }
    static int multiply(int a, int b) { return a * b; }
    static String divide(int a, int b) {
        if (b == 0) return "Error: Cannot divide by zero!";
        return String.valueOf(a / b);
    }

    static long power(int base, int exp) {
        long result = 1;
        for (int i = 0; i < exp; i++) result *= base;
        return result;
    }

    static long factorial(int n) {
        long result = 1;
        for (int i = 2; i <= n; i++) result *= i;
        return result;
    }

    static boolean isPrime(int n) {
        if (n <= 1) return false;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) return false;
        }
        return true;
    }

    static double calculateTotal(double[] prices) {
        double subtotal = 0;
        for (double p : prices) subtotal += p;
        return subtotal;
    }
    static double applyDiscount(double total, double percent) {
        return total * (1 - percent / 100);
    }
    static double addTax(double amount, double taxRate) {
        return amount * (1 + taxRate / 100);
    }

    public static void main(String[] args) {
        System.out.println("=== Mini Calculator ===\n");

        System.out.println("BASIC OPERATIONS:");
        System.out.println("  add(15, 7)      = " + add(15, 7));
        System.out.println("  subtract(20, 8) = " + subtract(20, 8));
        System.out.println("  multiply(6, 9)  = " + multiply(6, 9));
        System.out.println("  divide(100, 4)  = " + divide(100, 4));
        System.out.println("  divide(10, 0)   = " + divide(10, 0));

        System.out.println("\nADVANCED:");
        System.out.println("  power(2, 10)    = " + power(2, 10));
        System.out.println("  factorial(7)    = " + factorial(7));

        System.out.println("\nPRIME CHECKER:");
        int[] nums = {2, 7, 10, 13, 17, 20, 23, 29};
        for (int n : nums) {
            System.out.println("  " + n + " is " + (isPrime(n) ? "prime" : "not prime"));
        }

        System.out.println("\nCHAINING:");
        int result = add(multiply(3, 4), subtract(20, 5));
        System.out.println("  add(multiply(3,4), subtract(20,5)) = " + result);

        System.out.println("\nSHOPPING CART:");
        double[] prices = {29.99, 15.50, 8.99, 42.00};
        double subtotal = calculateTotal(prices);
        System.out.printf("  Subtotal: $%.2f%n", subtotal);
        double discounted = applyDiscount(subtotal, 10);
        System.out.printf("  After 10%% discount: $%.2f%n", discounted);
        double finalTotal = addTax(discounted, 8);
        System.out.printf("  After 8%% tax: $%.2f%n", finalTotal);
    }
}
public class Main {
    // 1) This method hands a number back, so it is not void.
    static ___ postage(double kg) {                 // 👉 replace ___ with double
        // 2) One argument in, two arguments out: call the other version.
        return postage(kg, ___);                    // 👉 replace ___ with false
    }

    // The overload: same name, different parameter list.
    static double postage(double kg, boolean tracked) {
        double base = 2.50 + kg * 1.20;
        // 3) Give the answer back to whoever called this method.
        ___ tracked ? base + 1.75 : base;           // 👉 replace ___ with return
    }

    // 4) This one only prints. It hands nothing back.
    static ___ describe(String label, double amount) {   // 👉 replace ___ with void
        System.out.printf("%-18s %.2f%n", label + ":", amount);
    }

    static void tryToChange(double kg) {
        kg = 99;                 // changes the COPY, not the caller's variable
    }

    public static void main(String[] args) {
        double parcel = 2.0;

        // 5) One argument picks the first overload, two picks the second.
        describe("Standard", postage(parcel));
        describe("Tracked", postage(parcel, ___));  // 👉 replace ___ with true

        tryToChange(parcel);
        System.out.println("Parcel weight is still " + parcel);
    }
}

Common Mistakes

int add(int a, int b) {
    int sum = a + b;
    // ❌ Forgot to return sum! Compiler error.
}
add(5, 3);  // ❌ Calculates 8 but throws it away!
int result = add(5, 3);  // ✅ Store the result

Clean Method Guidelines

💡 Single Responsibility: Each method should do ONE thing and do it well. calculateTax() — yes. calculateTaxAndPrintAndSaveToFile() — no!

💡 Descriptive names with verbs: calculateShippingCost(), isValid(), getUserName() — not calc(), check(), get().

💡 Keep methods small: Ideally 5-15 lines. Maximum 20-30 lines. If it's longer, break it up.

💡 Limit parameters: 0-3 parameters is ideal. If you need 4+, consider grouping them into an object.

💡 No surprises: A method named getTotal() should only return a total — it shouldn't also print something or save to a file.

📋 Quick Reference

ConceptSyntaxNotes
Void methodvoid methodName(params)Performs action, no return
Return methodint methodName(params)Must return matching type
Parametersmethod(int a, String b)Input data for the method
OverloadingSame name, different paramsCompile-time polymorphism
Static methodstatic int add(int a, int b)Call without creating an object
Pass-by-valuemethod(primitiveVar)Method gets a copy of the value
ScopeVariables inside { }Only visible within that block

🎉 Lesson Complete!

You now know how to write clean, reusable methods with parameters, return values, overloading, and proper scope! Methods are the foundation of organized Java code — every professional program is built from hundreds of small, focused methods.

Practice quiz

What does the return type 'void' mean for a method?

  • It returns an int
  • It cannot be called
  • It returns nothing
  • It returns a String

Answer: It returns nothing. A void method performs an action but does not return a value.

What is the difference between a parameter and an argument?

  • A parameter is the variable in the definition; an argument is the value passed in
  • They are the same thing
  • An argument is in the definition; a parameter is passed in
  • Parameters are only for void methods

Answer: A parameter is the variable in the definition; an argument is the value passed in. Parameters are named in the method definition; arguments are the actual values you pass when calling.

What is method overloading?

  • Calling a method too many times
  • A method that returns multiple values
  • A method that is too long
  • Multiple methods with the same name but different parameter lists

Answer: Multiple methods with the same name but different parameter lists. Overloading means several methods share a name but differ in their parameter lists.

Can you overload two methods that differ ONLY in their return type?

  • Yes, always
  • No — the parameter lists must differ
  • Only for void methods
  • Only with static

Answer: No — the parameter lists must differ. You cannot overload by return type alone; the parameter lists must differ.

Java passes arguments by value. What does that mean for a primitive like int?

  • The method gets a copy, so the original is unchanged
  • The method can change the original variable
  • The original becomes null
  • It throws an exception

Answer: The method gets a copy, so the original is unchanged. Java is pass-by-value: the method receives a copy of the value, so changes inside don't affect the original.

What does this print? static void d(int x){x*=2;} int num=10; d(num); System.out.println(num);

  • 20
  • 0
  • 10
  • An error

Answer: 10. d gets a copy of num; doubling the copy leaves the original num as 10.

What is variable scope in the context of methods?

  • How fast a method runs
  • Variables declared in a method are local and don't exist outside it
  • The number of parameters
  • The return type

Answer: Variables declared in a method are local and don't exist outside it. Variables declared inside a method are local to it — they cannot be seen from other methods.

Given 'static int add(int a, int b){return a+b;}', what does add(multiply(3,4), 5) return if multiply(3,4) is 12?

  • 12
  • 60
  • 20
  • 17

Answer: 17. multiply(3,4) is 12, then add(12, 5) returns 17.

How do you correctly use a method's returned value?

  • add(5, 3); on its own line
  • int result = add(5, 3);
  • void result = add(5, 3);
  • return add(5, 3);

Answer: int result = add(5, 3);. Store the result in a variable: int result = add(5, 3); calling it alone discards the value.

Which of these is a static method call that needs no object?

  • name.length()
  • name.toUpperCase()
  • Math.sqrt(16)
  • account.getBalance()

Answer: Math.sqrt(16). Math.sqrt is static — called on the class directly; the others are instance methods needing an object.

Continue this course