# AP® Computer Science A 3.5 Methods: How to Write Them

Source: https://lockincs.com/ap-csa/unit-3/3-5-methods-how-to-write-them/  
Last reviewed against the College Board Course and Exam Description (CED): 2026-11-12  
CED codes: 3.5.A, 3.5.A.1, 3.5.A.2, 3.5.A.3, 3.5.A.4, 3.5.A.5, 3.5.A.6, 3.5.A.7, 3.5.A.8

A void method does not return a value; a non-void method returns a single value of its return type, and this is called return by value. A return statement sends the flow of control back to the caller at once. Accessor methods give other classes a copy of a variable's value, mutator methods change it, and a primitive parameter is a copy of its argument.

## What you will learn

- 3.5.A Develop code to define behaviors of an object through methods written in a class using primitive values, and determine the result of calling these methods.

## 1\. void and non-void methods

The method **header** tells you whether a method returns a value.

| Kind | Header | Returns |
| --- | --- | --- |
| void method | `public void refill()` | nothing; the keyword `void` comes before the method name 3.5.A.1 |
| non-void method | `public int getAmount()` | a single value; the return type takes the place of `void` 3.5.A.2 |

Here is a complete class in the AP® free-response “class design” style. It is used in every section of this page.

```
public class WaterBottle
{
    private static int bottlesMade = 0;   // class variable

    private int capacity;   // in milliliters
    private int amount;     // in milliliters

    public WaterBottle(int maxMilliliters)
    {
        capacity = maxMilliliters;
        amount = maxMilliliters;
        bottlesMade++;
    }

    // ----- accessor methods (non-void) -----
    public int getAmount()
    {
        return amount;
    }

    public boolean isEmpty()
    {
        return amount == 0;
    }

    public double percentFull()
    {
        return 100.0 * amount / capacity;
    }

    public static int getBottlesMade()
    {
        return bottlesMade;
    }

    // ----- mutator methods (void) -----
    public void drink(int milliliters)
    {
        if (milliliters > amount)
        {
            amount = 0;
        }
        else
        {
            amount -= milliliters;
        }
    }

    public void refill()
    {
        amount = capacity;
    }

    public String toString()
    {
        return amount + "/" + capacity + " mL";
    }
}
```

```
WaterBottle bottle = new WaterBottle(750);
bottle.drink(300);
System.out.println(bottle.getAmount());
System.out.println(bottle.percentFull());
bottle.drink(500);
System.out.println(bottle.isEmpty() + " " + bottle);
bottle.refill();
System.out.println(bottle);
```

Output:

```
450
60.0
true 0/750 mL
750/750 mL
```

**Background:** `toString` lets `println` show the bottle as text. You will read `toString` methods in class code, but writing one is outside the AP® exam.

A call to a void method is a statement on its own (`bottle.refill();`). A call to a non-void method is an expression: its value is printed, stored or used in a calculation.

## 2\. Return by value

In a non-void method, a **return expression** that is compatible with the return type is evaluated, and that value is returned to the caller. This is called **return by value** 3.5.A.3.

```
public class Average
{
    public static double mean(int a, int b)
    {
        return (a + b) / 2.0;
    }

    public static int meanRounded(int a, int b)
    {
        return (int) ((a + b) / 2.0 + 0.5);
    }
}
```

```
System.out.println(Average.mean(7, 8));
System.out.println(Average.meanRounded(7, 8));
```

Output:

```
7.5
8
```

A `double` expression is not compatible with an `int` return type, so this does not compile:

```
public class BadAverage
{
    public static int mean(int a, int b)
    {
        return (a + b) / 2.0;
    }
}
```

Compiler says:

```
error: incompatible types: possible lossy conversion from double to int
```

A non-void method must return a value on every path through the method:

```
public class Grader
{
    public static String letter(int score)
    {
        if (score >= 90)
        {
            return "A";
        }
    }
}
```

Compiler says:

```
error: missing return statement
```

## 3\. return ends the method

The `return` keyword sends the **flow of control** back to the point where the method or constructor was called 3.5.A.4. Any code that comes after a return statement in sequence is never executed 3.5.A.4. A return statement inside a selection (`if`) or iteration (loop) statement stops that statement and exits the whole method or constructor 3.5.A.4.

This method searches a string and stops at the first digit it finds:

```
public class Finder
{
    /** Returns the index of the first digit in s, or -1 if none */
    public static int firstDigit(String s)
    {
        for (int i = 0; i < s.length(); i++)
        {
            String ch = s.substring(i, i + 1);
            if ("0123456789".indexOf(ch) >= 0)
            {
                return i;   // leaves the loop AND the method
            }
        }
        return -1;          // reached only if no digit was found
    }
}
```

```
System.out.println(Finder.firstDigit("Room 42B"));
System.out.println(Finder.firstDigit("Lobby"));
```

Output:

```
5
-1
```

A void method can use `return;` with no value to exit early:

```
public class Launch
{
    public static void countdown(int start)
    {
        for (int i = start; i >= 0; i--)
        {
            if (i == 2)
            {
                return;
            }
            System.out.println(i);
        }
        System.out.println("Liftoff!");
    }
}
```

```
Launch.countdown(5);
```

Output:

```
5
4
3
```

“Liftoff!” is never printed: the `return` ended the method, not only the loop.

Code placed directly after a return statement can never run, so the compiler rejects it:

```
public class Doubler
{
    public static int twice(int n)
    {
        return n * 2;
        System.out.println("done");
    }
}
```

Compiler says:

```
error: unreachable statement
```

## 4\. Accessors and mutators

An **accessor method** lets objects of other classes obtain a **copy of the value** of an instance variable or a class variable. An accessor is a non-void method 3.5.A.5. In `WaterBottle`, `getAmount` returns a copy of `amount`, and the class method `getBottlesMade` returns a copy of the class variable `bottlesMade`.

A **mutator method** (also called a modifier method) changes the values of instance variables or class variables. A mutator is often a void method 3.5.A.6. In `WaterBottle`, `drink` and `refill` are mutators.

```
WaterBottle a = new WaterBottle(500);
WaterBottle b = new WaterBottle(1000);
int copy = a.getAmount();
copy = 0;
b.drink(250);
System.out.println(a.getAmount() + " " + b.getAmount());
System.out.println(WaterBottle.getBottlesMade());
```

Output:

```
500 750
2
```

Changing `copy` did not empty bottle `a`: the accessor handed out a copy of the value, not the instance variable itself.

| Method | Accessor or mutator? | void? |
| --- | --- | --- |
| `getAmount()` | accessor | no, returns `int` |
| `isEmpty()` | accessor | no, returns `boolean` |
| `drink(int milliliters)` | mutator | yes |
| `refill()` | mutator | yes |

## 5\. Parameters and primitive values

Methods with **parameters** receive values through them and use those values to do their task 3.5.A.7. When the **argument** is a primitive value (`int`, `double`, `boolean`), the parameter is initialized with a **copy** of that value. Changes to the parameter have no effect on the argument 3.5.A.8. Passing copies of argument values like this is called **call by value** (you met it with constructors in topic 1.13).

```
public class Bonus
{
    public static int addBonus(int points)
    {
        points = points + 10;
        return points;
    }
}
```

```
int myPoints = 50;
int result = Bonus.addBonus(myPoints);
System.out.println(myPoints + " " + result);
```

Output:

```
50 60
```

Memory, step by step:

| Moment | `myPoints` (in the caller) | `points` (parameter) | `result` |
| --- | --- | --- | --- |
| Before the call | 50 | does not exist | does not exist |
| Start of `addBonus` | 50 | 50 (a copy) | does not exist |
| After `points = points + 10` | 50 | 60 | does not exist |
| After the call returns | 50 | gone | 60 |

**Watch out:** if the method should change the caller’s variable, the caller must store the returned value: `myPoints = Bonus.addBonus(myPoints);`.

## Common mix-ups

- Not true: A method can keep running after its return statement. return sends control back to the caller immediately. Code after it in the same block never runs (the compiler rejects it as unreachable), and a return inside a loop ends the loop and the method.
- Not true: If a method changes its int parameter, the caller's variable changes too. A primitive parameter is a copy of the argument's value. Changing the copy has no effect on the caller's variable.
- Not true: A method that prints a value returns it. Printing shows text in the console; returning gives a value back to the caller. A void method that prints cannot be used in an expression like int x = obj.show();

## In 30 seconds

- void method: no return value, keyword void in the header. Non-void method: return type in place of void, returns a single value.
- The return expression must be compatible with the return type; its value is returned (return by value).
- return sends control back to the caller; code after it never runs; a return inside a loop or if exits the whole method.
- Accessor: non-void, gives a copy of an instance or class variable's value. Mutator: changes the value, often void.
- Parameters receive values; a primitive parameter is a copy, so changing it does not change the argument.

## Checkpoint: 6 practice questions

### Question 1

Consider the following class. The code segment below the class appears in a method in another class. What is printed as a result of executing the code segment?

```java
public class Search
{
    public static int countUntil(String s, String target)
    {
        int count = 0;
        for (int i = 0; i < s.length(); i++)
        {
            if (s.substring(i, i + 1).equals(target))
            {
                return count;
            }
            count++;
        }
        return -1;
    }
}

System.out.println(Search.countUntil("banana", "n") + " " + Search.countUntil("kiwi", "a"));
```

- A. 3 -1
- B. 2 4
- C. 2 -1
- D. 4 -1

**Answer: C.** In "banana" the first "n" is at index 2. Before it, `count` was incremented twice (for "b" and "a"), and the return statement exits the loop and the method at once, so 2 is returned. "kiwi" has no "a", so the loop ends and -1 is returned. The option 3 -1 counts the matching letter too, and 4 -1 assumes the loop keeps running after the return.

### Question 2

Consider the following class. The code segment below the class appears in a method in another class. What is printed as a result of executing the code segment?

```java
public class Changer
{
    public static void update(int a, double b)
    {
        a = a * 2;
        b = b + 1.5;
        System.out.print(a + " " + b + " ");
    }
}

int x = 4;
double y = 2.0;
Changer.update(x, y);
System.out.print(x + " " + y);
```

- A. 8 3.5 8 3.5
- B. 8 3.5 4 2.0
- C. 4 2.0 4 2.0
- D. 8 3.5 4 2

**Answer: B.** The parameters `a` and `b` are copies of the values of `x` and `y`. Inside the method the copies become 8 and 3.5 and are printed. Changes to a primitive parameter have no effect on the argument, so `x` is still 4 and `y` is still 2.0. A `double` always prints with a decimal part, so 2 is wrong.

### Question 3

Consider the following incomplete class. Which of the following can replace `/* missing code */` so that `getFuel` is a correct accessor method, called as `c.getFuel()`?

```java
public class Car
{
    private double fuel;

    public Car(double startFuel)
    {
        fuel = startFuel;
    }

    /* missing code */
}
```

- A. `public double getFuel() { return fuel; }`
- B. `public void getFuel() { return fuel; }`
- C. `public int getFuel() { return fuel; }`
- D. `public double getFuel(double fuel) { return fuel; }`

**Answer: A.** An accessor is a non-void method whose return type matches the value it returns, so `public double getFuel()` returning `fuel` is correct. A void method cannot return a value. Returning a `double` from an `int` method is a possible lossy conversion and does not compile. The last option needs an argument and returns the parameter, not the instance variable.

### Question 4

The `Car` class has a mutator `addFuel` that is intended to increase `fuel` by `liters` without letting `fuel` go above 50.0. If adding `liters` would go above 50.0, `fuel` should become exactly 50.0. Which of the following can replace `/* missing code */` so that the method works as intended?

```java
public class Car
{
    private double fuel;

    public Car(double startFuel)
    {
        fuel = startFuel;
    }

    public void addFuel(double liters)
    {
        /* missing code */
    }
}
```

- A. `if (fuel + liters > 50.0) { return 50.0; } fuel += liters;`
- B. `fuel = liters; if (fuel > 50.0) { fuel = 50.0; }`
- C. `if (fuel + liters <= 50.0) { fuel += liters; }`
- D. `fuel += liters; if (fuel > 50.0) { fuel = 50.0; }`

**Answer: D.** Adding first and then capping at 50.0 handles both cases. A void method cannot return a value, so `return 50.0;` does not compile. `fuel = liters` replaces the fuel instead of adding to it. The `<=` version does nothing when the sum is too large, so a car with 45.0 that adds 10.0 stays at 45.0 instead of becoming 50.0.

### Question 5

The following method does not compile. Which of the following best explains why?

```java
public boolean isPassing(int score)
{
    if (score >= 60)
    {
        return true;
    }
    else if (score < 60)
    {
        return false;
    }
}
```

- A. The compiler cannot confirm that a return statement runs on every path
- B. A boolean method cannot contain more than one return statement
- C. The method must print its result before it returns
- D. A method with an int parameter must have an int return type

**Answer: A.** The compiler does not work out that the two conditions cover every score; it only sees that if both conditions were false, the method would reach its end without returning, so it reports a missing return statement. Changing `else if (score < 60)` to `else` fixes it. A method may have several return statements, does not need to print, and its return type does not depend on its parameter types.

### Question 6

Consider the following class. The code segment below the class appears in a method in another class. What is printed as a result of executing the code segment?

```java
public class Account
{
    private int balance;

    public Account(int start)
    {
        balance = start;
    }

    public int getBalance()
    {
        return balance;
    }

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

Account acct = new Account(100);
int b = acct.getBalance();
b += 50;
acct.deposit(20);
System.out.println(b + " " + acct.getBalance());
```

- A. 170 170
- B. 150 170
- C. 150 120
- D. 120 120

**Answer: C.** The accessor returns a copy of the value 100, so `b` becomes 150 without changing the account. The mutator `deposit` changes the instance variable from 100 to 120. The option 150 170 assumes that changing `b` also changed `balance`, and 170 170 treats `b` and `balance` as one variable.

## Questions students ask

**What is the difference between a void and a non-void method?**

A void method performs an action and returns nothing; its header has void before the name. A non-void method returns a single value; its header has a return type such as int, double, boolean or String instead of void.

**What is the difference between an accessor and a mutator?**

An accessor (getter) is a non-void method that returns a copy of an attribute's value without changing it. A mutator (setter or modifier) changes the value of an attribute and is often a void method.

**Does Java pass primitive values by value?**

Yes. When the argument is a primitive value, the parameter is initialized with a copy of that value, so changes to the parameter have no effect on the argument.

**What happens to code after a return statement?**

It is never executed. If it is in the same block, the compiler reports an unreachable statement error.

---

© LockInCS, licensed CC BY-NC-ND 4.0. AP® is a trademark registered by the College Board, which is not affiliated with, and does not endorse, this website.
