# Methods

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Control Flow
Source: https://www.devtutorials.ai/learn/java/control-flow/methods

> Write and call Java methods with parameters and return values, overload them, use static and instance methods, varargs and recursion, and see how pass by value works.

Think about a coffee machine.

You press one button, and the machine does a whole sequence of work: heat water, grind beans, and pour the coffee. You do not need to repeat those steps yourself every time. You just press the button again when you want another cup.

A method works the same way. You write a set of steps once, give it a name, and call that name whenever you want the job done again.

In simple words: a method is a named block of code that does one job, and you can run it as many times as you like.

## What You Will Learn

In this lesson, you will learn:

1. Why methods make programs shorter and easier to maintain.
2. How to declare a method and how to call it.
3. How to send values into a method with parameters.
4. How to get a value back with `return`, and when to use `void`.
5. How to give several methods the same name with overloading.
6. The difference between static methods and instance methods.
7. How to accept any number of values with varargs.
8. How a method can call itself with recursion.
9. What pass by value means, and why it often surprises beginners.

## Start With a Working Example

Press **Run**.

```java runnable title="One method, called three times"
public class Main {
    public static void main(String[] args) {
        greet("Asha");
        greet("Ravi");
        greet("Meena");
    }

    static void greet(String name) {
        System.out.println("Hello, " + name + "! Welcome to the course.");
    }
}
```

Expected output:

```text
Hello, Asha! Welcome to the course.
Hello, Ravi! Welcome to the course.
Hello, Meena! Welcome to the course.
```

The greeting is written once, inside the `greet` method. `main` calls it three times with different names.

### Try This

Change `Hello` to `Hi` inside `greet`. All three lines change, but you only edit one line.

## Introduction to Methods

A **method** is a block of code with a name. It runs only when it is called.

You have already used methods in your first programs:

- `main` is a method. Java calls it to start your program.
- `println` is a method. You call it to print text.
- `length()` and `toUpperCase()` are methods on a `String`.

Now you will write your own.

### Why Methods Help

- **No repeated code.** Write a job once, then call it wherever you need it.
- **Easier to fix.** If the job has a bug, you fix it in one place.
- **Easier to read.** A name like `calculateTax()` tells you what the code does.
- **Smaller pieces.** A big problem becomes a set of smaller, simpler methods.

This idea is often called **DRY**: Don't Repeat Yourself.

## Method Declaration

**Declaring** a method means writing it. A declaration has a header and a body.

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

| Part | Example | Meaning |
|---|---|---|
| Modifier | `static` | How the method can be called |
| Return type | `int` | The type of value the method gives back, or `void` for none |
| Name | `add` | What you call the method |
| Parameters | `(int a, int b)` | The values the method needs |
| Body | `{ return a + b; }` | The code that runs |

Methods are written inside a class, but outside any other method. You cannot put one method inside another.

Method names use **camelCase** and usually start with a verb: `calculateTotal`, `printReport`, `isValid`.

## Method Calling

**Calling** a method means running it. You write its name, followed by brackets.

When Java reaches a call, it:

1. jumps into the method;
2. runs the method's body from top to bottom;
3. jumps back to the line that made the call and continues.

```java runnable title="Java jumps into the method and comes back"
public class Main {
    public static void main(String[] args) {
        System.out.println("1. main starts");
        printLine();
        System.out.println("3. back in main");
        printLine();
        System.out.println("4. main ends");
    }

    static void printLine() {
        System.out.println("2. inside printLine");
    }
}
```

Expected output:

```text
1. main starts
2. inside printLine
3. back in main
2. inside printLine
4. main ends
```

`printLine` is written below `main`, but that does not matter. A method runs only when it is called, not when it is written.

Think of a phone call. You stop what you are doing, talk, hang up, and then continue from where you left off.

## Method Parameters

A **parameter** is a variable in the method header. It receives a value when the method is called.

The value you send in the call is called an **argument**.

```text
static void printBill(String item, int price) { ... }   // item and price are parameters

printBill("Pen", 20);                                  // "Pen" and 20 are arguments
```

```java runnable title="Arguments fill the parameters in order"
public class Main {
    public static void main(String[] args) {
        printBill("Notebook", 3, 45);
        printBill("Pen", 10, 12);
    }

    static void printBill(String item, int quantity, int price) {
        int total = quantity * price;
        System.out.println(item + " x" + quantity + " = " + total);
    }
}
```

Expected output:

```text
Notebook x3 = 135
Pen x10 = 120
```

The arguments are matched to the parameters **by position**. The first argument goes into the first parameter, and so on.

The number, types, and order must all match. `printBill(3, "Notebook", 45)` does not compile because `3` is not a `String`.

Parameters are local variables. They only exist inside their method.

## Return Values

A method can send a value back to the code that called it. This is called **returning** a value.

You do two things:

- write the type of the value before the method name, such as `int` or `double`;
- use the `return` keyword in the body to send the value back.

```java runnable title="return sends a value back to the caller"
public class Main {
    public static void main(String[] args) {
        double area = circleArea(7);
        System.out.println("Area: " + area);

        int bigger = max(18, 42);
        System.out.println("Bigger: " + bigger);

        System.out.println("Is 17 even? " + isEven(17));
    }

    static double circleArea(double radius) {
        return 3.14 * radius * radius;
    }

    static int max(int a, int b) {
        if (a > b) {
            return a;
        }
        return b;
    }

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

Expected output:

```text
Area: 153.86
Bigger: 42
Is 17 even? false
```

`circleArea(7)` is replaced by the value it returns, `153.86`. That value is stored in `area`.

You can use a method call anywhere you could use a value: in a variable, in a `println`, or inside a condition.

`return` also ends the method immediately. In `max`, if `a > b` is true, the line `return b;` never runs.

A method with a return type must return a value on every path. If one path can reach the end without a `return`, the compiler reports `missing return statement`.

## Void Methods

A **void** method does a job but returns nothing. Its return type is `void`.

Use `void` when the method's job is an action, like printing, saving, or updating something.

```java runnable title="A void method acts but gives nothing back"
public class Main {
    public static void main(String[] args) {
        printStars(5);
        printStars(3);
    }

    static void printStars(int count) {
        if (count <= 0) {
            return;
        }
        for (int i = 0; i < count; i++) {
            System.out.print("*");
        }
        System.out.println();
    }
}
```

Expected output:

```text
*****
***
```

A `void` method can still use `return;` with no value. It just leaves the method early.

You cannot store the result of a `void` method. `int x = printStars(5);` does not compile, because there is nothing to store.

| | `void` method | Method with a return type |
|---|---|---|
| Gives back a value? | No | Yes |
| `return` | Optional, written as `return;` | Required, written as `return value;` |
| Typical job | Print, save, change something | Calculate, check, find something |
| Example | `printStars(5);` | `int m = max(4, 9);` |

## Method Overloading

**Method overloading** means having several methods with the **same name** but **different parameters**.

Java picks the right one by looking at the arguments you pass.

Think of the word "play". You play a song, play a game, or play football. The word is the same, and the words after it tell you which meaning you want.

```java runnable title="Same name, different parameters"
public class Main {
    public static void main(String[] args) {
        System.out.println(add(2, 3));
        System.out.println(add(2, 3, 4));
        System.out.println(add(2.5, 3.5));
    }

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

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

    static double add(double a, double b) {
        return a + b;
    }
}
```

Expected output:

```text
5
9
6.0
```

- `add(2, 3)` has two `int` values, so Java calls the first version.
- `add(2, 3, 4)` has three values, so Java calls the second.
- `add(2.5, 3.5)` has two `double` values, so Java calls the third.

Overloaded methods must differ in the **number**, **types**, or **order** of their parameters.

A different return type alone is not enough. Two methods named `total()` that differ only by return type cannot live in the same class, because a call like `total()` would not tell Java which one you mean.

## Static Methods

A **static** method belongs to the **class** itself. You can call it without creating an object.

Every method so far has been `static`. `main` is static too, so Java can call it before any objects exist.

You call a static method by its name inside the same class, or with the class name from outside: `ClassName.method()`.

```java runnable title="Static methods are called on the class"
public class Main {
    public static void main(String[] args) {
        System.out.println(Converter.celsiusToFahrenheit(100));
        System.out.println(Converter.kmToMiles(10));
        System.out.println(Math.max(8, 15));
    }
}

class Converter {
    static double celsiusToFahrenheit(double c) {
        return c * 9 / 5 + 32;
    }

    static double kmToMiles(double km) {
        return km * 0.625;
    }
}
```

Expected output:

```text
212.0
6.25
15
```

`Converter.celsiusToFahrenheit(100)` works without any `Converter` object.

`Math.max` is a static method from Java's own `Math` class. That is why you write `Math.max`, not `new Math().max`.

Static methods suit jobs that only need their parameters, like conversions and calculations.

## Instance Methods

An **instance method** belongs to an **object**. It has no `static` keyword.

You first create an object with `new`. Then you call the method on that object with a dot.

An instance method can use the object's own data. Each object keeps its own values.

```java runnable title="Each object runs the method with its own data"
public class Main {
    public static void main(String[] args) {
        BankAccount asha = new BankAccount();
        BankAccount ravi = new BankAccount();

        asha.deposit(500);
        asha.deposit(200);
        ravi.deposit(1000);

        asha.showBalance("Asha");
        ravi.showBalance("Ravi");
    }
}

class BankAccount {
    int balance = 0;

    void deposit(int amount) {
        balance += amount;
    }

    void showBalance(String owner) {
        System.out.println(owner + " has " + balance);
    }
}
```

Expected output:

```text
Asha has 700
Ravi has 1000
```

`deposit` and `showBalance` are instance methods. `asha.deposit(500)` changes only Asha's balance. Ravi's account is a separate object with its own `balance`.

| | Static method | Instance method |
|---|---|---|
| Keyword | `static` | none |
| Belongs to | The class | One object |
| How to call | `ClassName.method()` | `object.method()` |
| Needs an object? | No | Yes, created with `new` |
| Can use the object's own data? | No | Yes |
| Example | `Math.max(3, 7)` | `name.length()` |

A static method cannot call an instance method directly. Inside `main`, calling a non-static method gives `non-static method ... cannot be referenced from a static context`. Make the method `static`, or call it on an object.

## Variable Arguments (varargs)

Sometimes you do not know how many values the caller will pass. **Varargs** (variable arguments) let a method accept **any number** of values of one type.

You write three dots after the type: `int... numbers`.

Inside the method, `numbers` is an array.

```java runnable title="One method accepts any number of values"
public class Main {
    public static void main(String[] args) {
        System.out.println(sum());
        System.out.println(sum(5));
        System.out.println(sum(10, 20, 30));
        System.out.println(sum(1, 2, 3, 4, 5, 6));
    }

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

Expected output:

```text
0
5
60
21
```

The same `sum` method works with no values, one value, or six values.

Two rules for varargs:

- A method can have only one varargs parameter.
- It must be the last parameter. `static void report(String title, int... scores)` is fine. `static void report(int... scores, String title)` is not.

`System.out.printf` and `String.format` use varargs. That is why they accept any number of values.

## Recursive Methods

A **recursive method** is a method that calls itself.

Each call works on a smaller part of the problem until the answer becomes obvious.

Think of Russian nesting dolls. You open one doll and find a smaller one inside. You keep opening dolls until you reach the smallest one, which does not open.

Every recursive method needs two parts:

- a **base case**, which answers directly and stops the recursion;
- a **recursive case**, which calls the method again with a smaller problem.

### Factorial

The factorial of 5, written `5!`, is `5 × 4 × 3 × 2 × 1`, which is `120`.

Notice that `5!` is `5 × 4!`, and `4!` is `4 × 3!`. So factorial can be defined using a smaller factorial.

```java runnable title="Factorial calls itself with a smaller number"
public class Main {
    public static void main(String[] args) {
        System.out.println("5! = " + factorial(5));
        System.out.println("1! = " + factorial(1));
    }

    static int factorial(int n) {
        if (n <= 1) {
            return 1;                       // base case
        }
        return n * factorial(n - 1);        // recursive case
    }
}
```

Expected output:

```text
5! = 120
1! = 1
```

Here is what happens for `factorial(4)`:

```text
factorial(4) = 4 * factorial(3)
                   factorial(3) = 3 * factorial(2)
                                      factorial(2) = 2 * factorial(1)
                                                         factorial(1) = 1     ← base case
                                      factorial(2) = 2 * 1 = 2
                   factorial(3) = 3 * 2 = 6
factorial(4) = 4 * 6 = 24
```

The calls go down until they reach the base case. Then the answers come back up, one multiplication at a time.

### Watching the Calls

This version prints a line on the way down and on the way back up:

```java runnable title="Recursion goes down to the base case, then back up"
public class Main {
    public static void main(String[] args) {
        countDown(3);
    }

    static void countDown(int n) {
        if (n == 0) {
            System.out.println("Lift off!");
            return;
        }
        System.out.println("Going down: " + n);
        countDown(n - 1);
        System.out.println("Coming back: " + n);
    }
}
```

Expected output:

```text
Going down: 3
Going down: 2
Going down: 1
Lift off!
Coming back: 1
Coming back: 2
Coming back: 3
```

Each call waits for the call inside it to finish. So the "Coming back" lines print in reverse order.

A recursive method with no base case, or one that never reaches it, keeps calling itself. Each call uses a little memory, and the program soon stops with a `StackOverflowError`.

## Pass by Value

When you call a method, Java gives it a **copy** of each argument. This is called **pass by value**.

The method works on its copy. Changing the copy does not change the original variable in the caller.

Think of photocopying a page and handing over the copy. If someone writes on the copy, your original page stays clean.

```java runnable title="The method changes its copy, not the original"
public class Main {
    public static void main(String[] args) {
        int score = 50;
        addBonus(score);
        System.out.println("score in main: " + score);
    }

    static void addBonus(int score) {
        score += 10;
        System.out.println("score in addBonus: " + score);
    }
}
```

Expected output:

```text
score in addBonus: 60
score in main: 50
```

`addBonus` got a copy of `50` and changed its copy to `60`. The `score` in `main` was never touched.

To get the new value out, return it: `score = addBonus(score);`, with `addBonus` returning an `int`.

### Passing an Array or an Object

For arrays and objects, the variable holds a **reference**, which is like an address. Java still passes a copy, but it is a copy of the **address**.

Both copies point to the same array. So a change made **through** the reference is seen by the caller.

```java runnable title="A copied reference still points to the same array"
public class Main {
    public static void main(String[] args) {
        int[] marks = {70, 80, 90};

        addGrace(marks);
        System.out.println("After addGrace: " + marks[0] + ", " + marks[1] + ", " + marks[2]);

        replace(marks);
        System.out.println("After replace:  " + marks[0] + ", " + marks[1] + ", " + marks[2]);
    }

    static void addGrace(int[] list) {
        for (int i = 0; i < list.length; i++) {
            list[i] += 5;
        }
    }

    static void replace(int[] list) {
        list = new int[] {0, 0, 0};
    }
}
```

Expected output:

```text
After addGrace: 75, 85, 95
After replace:  75, 85, 95
```

`addGrace` changes the values inside the shared array, so `main` sees the change.

`replace` points its own copy of the reference at a brand-new array. That changes only the copy. `main` still points to the old array, so nothing changes there.

In simple words: Java always passes a copy. For a primitive, it copies the value. For an array or object, it copies the address, so both sides can reach the same object.

## Common mistakes

The following mistakes are common when writing and calling methods. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `incompatible types` at a method call | Arguments are in the wrong order or type | Match the parameter list exactly |
| `missing return statement` | One path has no `return` | Return a value on every path |
| The method's result never appears | The returned value was not stored or used | Store it in a variable, or print it |
| `non-static method cannot be referenced from a static context` | `main` called an instance method directly | Make the method `static`, or call it on an object |
| A variable is unchanged after a method call | Java passed a copy of the value | Return the new value and store it |
| `StackOverflowError` | Recursion never reaches its base case | Add a base case and make each call smaller |

## What to Remember

- A method is a named block of code. Declare it once, then call it as often as you need.
- Parameters receive values. The values you pass in a call are arguments, matched by position.
- A method with a return type must `return` a value. A `void` method returns nothing.
- Overloaded methods share a name but have different parameters.
- Static methods belong to the class. Instance methods belong to an object created with `new`.
- Varargs (`int... values`) accept any number of values as an array. It must be the last parameter.
- A recursive method calls itself and needs a base case to stop.
- Java always passes a copy. For an array or object, the copy still points to the same object.

Next: Arrays
