3.8 Instance Variables

Instance Variables vs Local Variables in Java

Unit 3: Methods, Worlds, and Constructors · Lesson 3.8 · about 35 minutes · no coding experience needed

This is the single most confusing bug in the whole course, and it produces a program that compiles, runs, and displays a score of zero forever. There is no error message. There is only a number that will not move.

What you will be able to do

  • Explain why a variable declared inside act() resets every frame
  • Declare an instance variable in the right place
  • Explain why each object gets its own copy

Words you will need

Local variable
In plain words Lives inside one method, and dies when it finishes.
More precisely A variable declared inside a method or block; its lifetime is that block.
Instance variable
In plain words Belongs to the object, and lasts as long as the object.
More precisely A field declared in the class body; each instance has its own copy.
private
In plain words Only this class can touch it.
More precisely An access modifier restricting visibility to the declaring class.

Build it step by step

Every step below leaves a scenario that compiles and runs. If you stop halfway you will have something that works, not something broken. Follow along in Greenfoot rather than reading straight through.

  1. Step 1

    On your screen A score variable declared inside the act method, with the world showing a score stuck at one.

    // BROKEN. The score never grows past 1.
    public void act()
    {
        int score = 0;
        if (isTouching(Coin.class))
        {
            removeTouching(Coin.class);
            score = score + 1;
        }
    }

    Read this carefully, because it looks completely reasonable.

    act() runs every frame. Every frame, the FIRST thing it does is `int score = 0;`, building a brand new box and putting zero in it. Whatever last frame counted is gone before this frame even checks for a coin.

    It compiles. It runs. The score is 1 at best, and usually 0. No error, ever.

  2. Step 2

    On your screen The same variable moved outside act, into the class body, with the score now climbing.

    public class Player extends Actor
    {
        private int score = 0;      // OUTSIDE act, inside the class
    
        public void act()
        {
            if (isTouching(Coin.class))
            {
                removeTouching(Coin.class);
                score = score + 1;
            }
        }
    }

    One line moved. That is the entire fix.

    `score` now belongs to the OBJECT rather than to one run of one method. It is created once, when the player is created, and it survives every frame after that.

    Look at where it sits: inside the class braces, outside every method. That position is what makes it an instance variable, not the word private.

  3. Step 3

    On your screen Two player actors in the same world with different scores shown.

    And each OBJECT gets its own. Two players in the world means two separate scores, counting independently.

    That is 1.3 coming back: objects share behavior, because that comes from the class, but they do not share state. An instance variable is exactly the state that is not shared.

  4. Step 4

    On your screen A getter method returning the private score field.

    private int score = 0;
    
    public int getScore()
    {
        return score;
    }

    `private` means only this class can touch the variable directly. That sounds inconvenient and is actually protection: nothing else can set your score to a million by accident.

    When something outside genuinely needs to know, you give it a method. `getScore()` hands the value out without handing over control, which is exactly the return type work from 3.4.

Mistakes almost everyone makes here

These are the wrong ideas students actually build at this point. Read them even if you think you understand, because a wrong idea you have not noticed is the expensive kind.

Common wrong idea Declaring a variable inside act() is fine as long as you assign to it.

What is actually true It is rebuilt from scratch every frame. Nothing survives.

Why it matters This is THE bug of Unit 3, and it produces no error at all.

Common wrong idea An instance variable is shared by every object of the class.

What is actually true Each object gets its own copy.

Why it matters This is what makes per-enemy health and per-player score possible.

Common wrong idea private stops the variable working.

What is actually true private only limits who can touch it directly. The class itself uses it normally.

Why it matters Students often make everything public to "fix" a problem that was never about access.

Common wrong idea The word private is what makes it an instance variable.

What is actually true Its POSITION does: inside the class, outside every method.

Why it matters A variable inside act() is local whether or not you write private, and writing private there is a compiler error.

Check your understanding

Answer these before moving on. They are graded instantly and you can retry.

  1. 1. A score declared as `int score = 0;` on the first line of act(). What happens over many frames?

  2. 2. Where must a variable go to survive between frames?

  3. 3. Two Player objects both have `private int score`. How many scores are there?

  4. 4. What does `private` do?

  5. 5. A student says their score is stuck at 0 and there is no error. What do you check first?

Fill in the code

Give this player a lives counter that starts at 3 and survives between frames. Put it in the right place and keep it protected.

public class Player extends Actor
{
     int lives = ;

    public void act()
    {
        if (isTouching(Spike.class))
        {
            lives = lives  1;
        }
    }
}
Stuck? Open a hint for each blank
  • Blank 1: The keyword that limits direct access to this class only.
  • Blank 2: How many lives does the player start with?
  • Blank 3: Touching a spike costs one.

Lesson quiz

This one counts toward your progress. Take it when the section above makes sense.

  1. 1. A variable declared inside a method:

  2. 2. What makes a variable an instance variable?

  3. 3. Three Enemy objects each have `private int health = 10;`. One takes 4 damage. What are the three healths?

  4. 4. Why give a private field a public getter method?

  5. 5. A score is stuck at 1 rather than 0. What does that suggest?

The short version

  • A variable declared inside a method is rebuilt every time that method runs.
  • act() runs every frame, so a score declared there resets every frame.
  • An instance variable goes inside the class and outside every method.
  • Each object gets its own copy. Position makes it an instance variable, not private.

If you get stuck

These pages cover the problems that come up most often in this lesson. Opening one is not cheating and it is not counted against you.

Get in Touch

Whether you're a student, parent, or teacher — I'd love to hear from you.

Just want free AP CS resources?

Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]