The Stacks
UNIT 3: CLASS CREATION · TOPIC 3.5

3.5 Methods: How to Write Them

Writing methods that read and change an object's state. The exam expects accessors, mutators, and a toString that returns — not prints — a String.

What you need to know

  • Method structure: public returnType name(parameters) { body }. A non-void method must return a value of the declared type on every path.
  • Accessors return an instance variable's value: public int getCount() { return count; }. They never change state.
  • Mutators change instance variables and are usually void: public void setCount(int c) { count = c; }. They may validate first.
  • public String toString() returns a String description of the object. System.out.println(obj) calls it automatically. It returns; it does not print.
  • A method can call other methods of the same class by name, and can use instance variables directly.
  • Reaching the end of a non-void method without a return is a compile-time error ("missing return statement"). A return inside an if isn't enough unless every branch returns.
  • Parameters are local to the method; changing a primitive parameter doesn't affect the caller's variable.

Worked example

public class Counter
{
    private int count;
    private String label;

    public Counter(String l) { label = l; count = 0; }

    public int getCount() { return count; }                 // accessor
    public void increment() { count++; }                    // mutator
    public void reset() { count = 0; }                      // mutator
    public boolean isPositive() { return count > 0; }       // accessor
    public String toString()
    {
        return label + ": " + count;                        // returns, not prints
    }
}
Counter c = new Counter("clicks");
c.increment();
c.increment();
System.out.println(c);        // clicks: 2
Exam tip: If the prompt says "returns," write return; if it says "prints," write System.out.println. Mixing them up is a full rubric point. For toString, always return. For every non-void method, ask: does every possible path hit a return?

Going deeper

The nuance, edge cases, and connections that turn a 3 into a 5.

  • Every path must return in a non-void method. The compiler checks this. if (x > 0) return 1; alone won't compile — what if x ≤ 0? Add an else, or a return after the if.
  • Accessor naming: getName(), getBalance(), and for booleans isActive(), hasItems(). The exam follows these conventions, and FRQ 2 prompts often specify the exact names.
  • Mutator with validation: a setter can reject bad values: public void setAge(int a) { if (a >= 0) age = a; }. This is why encapsulation matters — the class controls what's valid.
  • Mutators that return a status: public boolean withdraw(double amt) that returns whether it succeeded. Common in FRQ 2. Read the prompt for what it should return.
  • toString() must be public String toString() exactly — that signature is what println and string concatenation look for. It returns the description. If it prints instead, println(obj) prints the description and then prints the returned null or empty — wrong.
  • Methods can call other methods of the same class by bare name (total = computeSubtotal() + tax;). This is how you avoid duplication inside a class.
  • Local variables in methods are for intermediate work. They vanish when the method returns. If something needs to persist between calls, it's an instance variable.
  • A method that modifies an instance variable and one that reads it can be in the same class without conflict — they're operating on the same field of the same object.

Mistakes that cost points

  • Missing return on a path. Compile error. Every branch of a non-void method must return.
  • Printing in toString. Return the String. Don't print it.
  • Returning from a void method with a value. return x; in a void method — compile error. Bare return; is fine.
  • Reading the FRQ verb wrong. "Returns" → return. "Prints" → println. They're different rubric points.

Practice questions

Written in the style of the real exam. Try each one before revealing the answer.

Q1 Which of the following methods will cause a compile-time error?
  1. A public int f(int x) { if (x > 0) { return 1; } return -1; }
  2. B public int g(int x) { if (x > 0) { return 1; } }
  3. C public void h(int x) { if (x > 0) { return; } }
  4. D public boolean k(int x) { return x > 0; }
Show answer

Answer: B. If x ≤ 0, g reaches the end without returning an int — missing return statement.

Q2 A class has the method public String toString() { return "Item: " + name; }. What does System.out.println(item); print, where item has name "pen"?
  1. A Item: pen
  2. B A memory address
  3. C pen
  4. D Nothing; toString must be called explicitly
Show answer

Answer: A. println calls toString on the object automatically.

Key vocabulary

Accessor method
returns the value of an instance variable without changing it
Mutator method
changes an instance variable; typically void
toString
a method returning a String representation of the object, called automatically by println