← Java tutorials

LESSON 18 / 40 · FREE TUTORIAL

An Army of Objects

Reference object interaction and null

90–110 minutesThis chapter uses JDK 21 and does not require the preview function.Object-oriented Introduction

WHAT YOU WILL MAKE

Create player and pet interactive team

Will understand object variables as references; can explain the effect of two variables pointing to the same object; can handle null before using the object; can allow players to interact safely with pets through parameters. Prerequisites: declares classes, creates objects, accesses fields and calls instance methods. Today we need to see clearly where the "coordinate paper" of the object variable points.

Before you start: It is recommended to complete Lesson 17 first

Two tags may find the same wolf
  1. #1 · Pet objectname = shadow
    health = 17
VariableRefers to
shadow#1
alias#1

01 / 14

Before you begin: Put the examples in the right place

This chapter uses JDK 21 and does not require the preview function. A complete program is given for each common example, saved with annotated file names. Multiple examples are placed in their own folders to avoid auxiliary classes with the same name.

Terminal command: Replace the Chinese placeholder with the actual name

javac -encoding UTF-8 ExampleFile.java
java ExampleClass

Class names are case-sensitive. If the complete challenge code is divided into multiple sections, please connect them in the same file in order. Do not create separate classes for the continued sections. Run verification only lists the program output; additional input sequences are provided where input is required.

02 / 14

Reference image object coordinates

Object variables do not directly hold all data like int. It holds a reference that allows programs to find the object and access fields or methods.

The object variable stores a reference
  1. #1 · Pet objectname = shadow
    health = 20
VariableRefers to
wolf#1

L18Example01.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example01 {
    public static void main(String[] args) {
        PetWolf wolf = new PetWolf();
        wolf.name = "Shadow";
        System.out.println(wolf.name);
    }
}

Output

Shadow

Reading route

  • new PetWolf() creates the object.
  • wolf holds a reference to this object.
  • wolf.name follows the reference to find the field.
  • wolf.heal(3) calls the method along the reference.

03 / 14

Two variables share an object

Reference assignment copies the reference. first and second point to the same object, so after modifying health through second, first reads the new value.

Two references can point to the same pet
  1. #1 · Pet objectname = shadow
    health = 1
VariableRefers to
first#1
second#1

Arrows indicate reference relationships; objects are not automatically copied.

L18Example02.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example02 {
    public static void main(String[] args) {
        PetWolf first = new PetWolf();
        PetWolf second = first;
        second.health = 1;
        System.out.println(first.health);
        System.out.println(first == second);
    }
}

Output

1
true

04 / 14

null means there is no object

The object variable may not point to any object temporarily, and the value is null at this time. If the left side of the dot is null, the program cannot find the field or method.

Null reference has no coordinates to go to
  1. nullThere is currently no object
  2. CheckFirst determine whether it is non-null
  3. ExistCall object method
  4. missingPrompt or return failure

L18Example03.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example03 {
    public static void main(String[] args) {
        PetWolf selected = null;
        if (selected != null) System.out.println(selected.name);
        else System.out.println("No pet selected yet");
    }
}

Output

No pet selected yet

05 / 14

Pass the object to the method

Objects can be passed into methods as parameters. What is passed in is still a reference, so the method modifies the object state, and the caller can see the change.

Method parameters can also receive object references
  1. Actual parametersPass in a reference value
  2. Formal parametersReceive a copy of the reference value
  3. Change objectThe caller sees the status change
  4. Change parametersDo not change the caller's reference

L18Example04.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example04 {
    static void healPet(PetWolf pet, int n) {
        if (pet != null) pet.heal(n);
    }
    static void replacePet(PetWolf pet) { pet = new PetWolf(); }
    public static void main(String[] args) {
        PetWolf wolf = new PetWolf(); wolf.health = 12;
        healPet(wolf, 5);
        replacePet(wolf);
        healPet(null, 5);
        System.out.println(wolf.health);
    }
}

Output

17

06 / 14

Objects interact through methods

Object interaction is not about letting one class change the fields of another class casually. A clearer way is to call the other party's method.

The player takes action and the pet maintains its own status
  1. PlayerResponsible for selecting interactive objects
  2. feedCall pet eat
  3. PetWolfMaintain trust scope
  4. missingHandle null explicitly

L18Example05.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
class Player {
    void feed(PetWolf pet) { if (pet != null) pet.eat(); }
}
public class L18Example05 {
    public static void main(String[] args) {
        Player alex = new Player();
        PetWolf pet = new PetWolf();
        alex.feed(pet);
        alex.feed(null);
        System.out.println(pet.trust);
    }
}

Output

10

07 / 14

Changing the reference is different from changing the object

second.health = 5 modifies the object; second = new PetWolf() changes the reference saved by second. first still points to the old object.

Reassignment only changes that reference
  1. #1 · Object Ahealth = 20
  2. #2 · Object Bhealth = 5
VariableRefers to
first#1
second#2

L18Example06.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example06 {
    public static void main(String[] args) {
        PetWolf first = new PetWolf();
        PetWolf second = first;
        second = new PetWolf();
        second.health = 5;
        System.out.println(first.health + "," + second.health);
        System.out.println(first == second);
    }
}

Output

20,5
false

08 / 14

Reference equality and content equality

Using == on an object compares whether two references point to the same object. Two pets with the same name may still be different people.

Whether double equal sign comparison points to the same object
  1. ==Compare citation identities
  2. sameNameThis example compares name content
  3. Same nameDoes not represent the same object
  4. equalsWhether rewriting will affect semantics

L18Example07.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
    boolean sameName(PetWolf other) {
        return other != null && java.util.Objects.equals(name, other.name);
    }
}
public class L18Example07 {
    public static void main(String[] args) {
        PetWolf a = new PetWolf(); a.name = "Shadow";
        PetWolf b = a;
        PetWolf c = new PetWolf(); c.name = "Shadow";
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a.sameName(c));
    }
}

Output

true
false
true

09 / 14

Object Legion Test Bench

When testing the object program, record which object the variable points to and the current field value of each object.

Testing reference graphs is more reliable than just looking at the output
  1. new twiceVerify independent status
  2. Shared assignmentVerify that modifications are visible
  3. RedirectVerify that old references have not changed
  4. nullVerification Security Rejection
Acceptance and inspection forms
SceneOperationExpected
Independentnew twiceThe two objects do not affect each other
Shareb = aAfter b is modified, a can also see
Change quoteb = new PetWolf()a still points to the old object
Null referenceb = nullDo not call method after checking

10 / 14

null Fault Clinic

NullPointerException usually gives a specific line number. Find all dots in this line and check the source of each object variable.

Find the first dangerous point number along the exception stack
  1. Look at the line numberLocate your own code
  2. Find referencesLeft side of checkpoint number
  3. Check the sourceTrack assignment and return
  4. RepairArrange branches for missing objects

L18Example09.java · Complete independent example

class PetWolf {
    String name;
    int health = 20;
    int trust;
    void heal(int n) {
        if (n > 0) health += Math.min(n, 20 - health);
    }
    void eat() { trust += Math.min(10, 100 - trust); }
}
public class L18Example09 {
    static PetWolf findPet(String name) { return null; }
    public static void main(String[] args) {
        PetWolf found = findPet("Shadow");
        if (found != null) found.heal(5);
        else System.out.println("There is no such pet");
    }
}

Output

There is no such pet

Emergency sequence

  • Read the exception type and the first line of your own code.
  • Circle the object variable to the left of the dot.
  • Track where it is assigned or returned from.
  • Choose to check for null, provide a default object, or reject input.

11 / 14

Challenge Blueprint Players and Pets

The challenge program is called PlayerPetTeam. The player holds the current pet reference; it cannot be fed or treated until the selection is successful.

Three object methods to complete feeding, treatment and selection
  1. Player.selectedSave current selection
  2. PetWolfMaintain life and trust
  3. InteractionCall pet method
  4. Cancelnull clear selection

Acceptance conditions

  • The two pets are independent objects.
  • After the player selects the first pet and feeds it, the trust value increases.
  • Point another variable to the same pet and treat it, and the original reference sees new life.
  • After deselecting is set to null, the interaction returns false instead of crashing.
Acceptance and inspection forms
MethodEnterOutput or effect
selectPetWolfSave current reference
feedSelectedNoneTrust increased or false
healSelectedQuantityLife increased or false
statusNonePrint pet status

12 / 14

Challenge Realization Player Pet Team

Create new PlayerPetTeam.java. Predict each line of output before running, and then draw the objects pointed to by alex.selected, alias, shadow, and snow.

Reference relationships become verifiable behavior in the complete program
  1. Select shadowselected points to shadow
  2. FeedingTrust increased by 10
  3. alias treatmentThe original object's life changes to 17
  4. CancelInteraction returns false

PlayerPetTeam.java · Section 1/2, sequentially connected to the same file

public class PlayerPetTeam {
    static class PetWolf {
        String name;
        int health = 20;
        int trust = 0;
        void eat() { trust += Math.min(10, 100 - trust); }
        void heal(int n) {
            if (n > 0) health += Math.min(n, 20 - health);
        }
        void status() {
            System.out.println(name + " Life=" + health + " Trust=" + trust);
        }
    }
    static class Player {
        String name;
        PetWolf selected;
        void select(PetWolf pet) { selected = pet; }
        boolean feedSelected() {
            if (selected == null) return false;
            selected.eat(); return true;
        }
        boolean healSelected(int n) {
            if (selected == null || n <= 0) return false;
            selected.heal(n); return true;
        }
    }
    public static void main(String[] args) {
        PetWolf shadow = new PetWolf(); shadow.name = "Shadow";

PlayerPetTeam.java · Section 2/2, sequentially connected to the same file

        PetWolf snow = new PetWolf(); snow.name = "Snowball";
        shadow.health = 12;
        Player alex = new Player(); alex.name = "Alex";
        alex.select(shadow);
        System.out.println(alex.feedSelected());
        PetWolf alias = shadow;
        alias.heal(5);
        shadow.status();
        snow.status();
        alex.select(null);
        System.out.println(alex.healSelected(3));
    }
}

Output

true
Shadow Life=17 Trust=10
Snowball Life=20 Trust=0
false

13 / 14

Expansion tasks and clearance review

In addition to the code, the homework also requires a reference diagram: variables are drawn as labels, objects are drawn as squares, and arrows are used to connect them.

Three-speed task training object arrow
  1. Wooden PickaxeProve that shared modifications are visible
  2. Iron PickaxeProve that parameters are passed by value
  3. Diamond PickaxeThree pet selection system
  4. ReviewDraw variable and object arrows

Third gear operation

  • Wooden Pickaxe: Create a Mob, let two variables share it and prove that modifications are visible.
  • Iron Pick: Write the method heal(Mob target, int amount), safely handle null, and prove that reassigning parameters does not change the caller's reference.
  • Diamond Pickaxe: Make a selection system for three pets, supporting selection, cancellation, feeding and status query.
Acceptance and inspection forms
Self-evaluationCanStill need to practice
I can draw reference arrows□□
I can explain shared objects□□
I will handle null safely□□

14 / 14

Own acceptance record

Write expectations before running, and record actual results after running. Normal cases show that the program does things; edge cases show that it knows when to stop; error cases show that it rejects unreasonable requests.

Write the evidence into the record
CategoryInput of your choiceExpectation and actual
NormalA common value or a successful operationIs it consistent line by line?
BorderMinimum value, maximum value and adjacent valueIs there one less square and one more step?
ErrorIllegal quantity, missing object or incorrect syntaxExplicitly reject? Is the status maintained?
  • Write a bug as: triggering conditions, phenomena, causes, and minimal repairs.
  • Organize a rule worth remembering and explain it in your own words. Don't just copy the definition.
  • Change an example, keep a record of the test, and let the results prove your understanding.

TAKE IT WITH YOU

Take the lesson offline

The complete lesson, code, diagrams and exercises, in your preferred language.