Skip to content

VOL 01 / CH 07 / LESSON 02

7.2 Fields, Methods, and this

Prerequisites: Classes, Objects, Reference Variables, and Methods

Estimated time: 25 minutes

You are ready to continue when: You can write methods that maintain object state and explain this and Java pass-by-value

1. Instance Method Operations on the Current Object State

java
class Book {
    String title;
    boolean borrowed;

    boolean borrow() {
        if (borrowed) {
            return false;
        }
        borrowed = true;
        return true;
    }

    boolean returnBook() {
        if (!borrowed) {
            return false;
        }
        borrowed = false;
        return true;
    }

    String description() {
        return title + ", borrowed: " + borrowed;
    }
}

Calling an instance method requires a receiver:

java
public class Library {
    public static void main(String[] args) {
        Book book = new Book();
        book.title = "Java Study Notes";

        System.out.println(book.borrow());
        System.out.println(book.borrow());
        System.out.println(book.description());
    }
}

Output:

text
true
false
Java Study Notes, borrowed: true

The second loan returns false, avoiding the "duplicate lending" state. You could also choose to throw IllegalStateException, but the class should maintain consistent contract.

When calling book.borrow(), book is the receiver. The method body runs on that object, allowing direct access to its instance fields. If the receiver is null, the method body does not start executing, and instead throws NullPointerException.

2. this Represents the Current Receiver

When parameter names and field names are the same, the unqualified name refers to the parameter:

java
class Student {
    String name;

    void rename(String name) {
        this.name = name;
    }
}

this.name is a field of the current object, and name is a parameter. When there is no conflict, this is usually omitted:

java
boolean isBorrowed() {
    return borrowed;
}

this is not a reassignable ordinary variable and cannot appear in a static context, since static methods do not have a current object. The this(...) in a constructor is another syntax used to invoke other constructors of the same class. This will be explained in detail in the next lesson.

3. Method calls always pass arguments by value.

java
static void rename(Book book) {
    book.title = "New book title";
}

static void replace(Book book) {
    book = new Book();
    book.title = "Local object";
}

When rename(original) and replace(original) are called, each parameter receives a copy of the referenced value from original:

  • rename uses the copied reference to modify the shared object, which the caller can observe.
  • replace assigns a new reference only to the local parameter; the caller’s variable stays unchanged.

Java does not have two sets of parameter rules ("value semantics for primitives and reference semantics for objects") only one rule: the value of the actual parameter expression is copied to the formal parameter; in the object case, this value is exactly a reference value.

4. Returning this Enables Fluent Calls

java
class ReadingProgress {
    private int page;

    ReadingProgress moveTo(int page) {
        if (page < 0) {
            throw new IllegalArgumentException("negative page");
        }
        this.page = page;
        return this;
    }

    int page() {
        return page;
    }
}

The caller can write progress.moveTo(10).moveTo(20). This is suitable for configurators and builders, but for business commands with complex failure strategies, sequential calls are often clearer.

5. Different Lifecycles of Fields and Local Variables

Instance fields exist with objects and have default values. Method parameters and local variables are only relevant during a single method call and must be explicitly assigned before they can be read. Do not treat them as the same storage location just because they have the same name.

java
class Counter {
    int total; // Default to new object 0

    void add(int amount) { // amount Belongs to this call
        int previous = total; // previous Also a local variable
        total = Math.addExact(previous, amount);
    }
}

These fields have package access, so other code in the same package can change them directly and bypass the methods’ rules. In this example, simplicity is maintained to first understand object behavior. In the encapsulation section, fields will be changed to private, and only necessary operations will be made public.

Professional Quick Reference

QuestionConclusion
Which object does an instance method operate onThe receiver object of the called expression
Who is thisThe current receiver
Null receiverThrows NullPointerException before the method body starts
What is passed as an object parameterA copy of the reference value
Reassigning a parameterDoes not replace the caller's variable
Modifying the object pointed to by a parameterShared alias can be observed

Before Moving On

Run the same book twice consecutively for borrow and twice for returnBook to ensure that illegal states do not sneak in unnoticed. Use a reference graph to explain that rename(original) modifies shared objects, while replace(original) only rewrites parameter copies; also, indicate the fields and parameters on both sides of this.name = name.

Next: Constructors and Object Invariants

Built with VitePress | Software Systems Atlas