Java Instance Variables

In the last lesson you learned about Java local variables. The fields you write inside classes, like name and age, have a proper name: instance variables. Java has a few kinds of variables, so let’s sort them out.

πŸ€” Three kinds of variables

A variable’s kind depends on where you declare it and who owns it. There are three:

  • An instance variable is declared in the class and belongs to each object. Every object gets its own copy.
  • A static variable uses the static keyword and is shared by all objects. One copy total.
  • A local variable is declared inside a method and exists only while that method runs.

Fields like name and age are instance variables, the most common kind. We start there.

🧍 Instance variables: one per object

The word instance means one object, so an instance variable is one each object owns by itself.

  • Every object gets its own separate copy.
  • Changing one object’s copy does not touch another’s.
  • The copies are fully independent.

This program creates two Student objects and gives each one its own name, then prints them both:

public class Main {
public static void main(String[] args) {
Student s1 = new Student();
s1.name = "Alex";
Student s2 = new Student();
s2.name = "Riya";
System.out.println(s1.name); // βœ… Alex
System.out.println(s2.name); // βœ… Riya, unaffected by s1
}
}
class Student {
String name; // instance variable: each object has its own
}
  • s1 and s2 each carry their own name.
  • Setting s2.name to β€œRiya” leaves s1.name at β€œAlex”. They never interfere.
  • You reach the value through the object with a dot: s1.name.
  • Most class data is per-object (name, age, balance, score), so most of it is instance variables.

Output

Alex
Riya

🧠 Default values: instance variables start filled in

When you create an object, Java fills its instance variables with a safe starting value automatically. These are the defaults:

  • Number types like int, long, short, byte start at 0.
  • Decimal types double and float start at 0.0.
  • A boolean starts at false.
  • A char starts at the blank character (code 0).
  • Any object type, like String, starts at null, which means β€œpoints to nothing yet”.

This program makes a Student but never assigns any field, then prints them to show the defaults:

public class Main {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.name); // βœ… null (object type default)
System.out.println(s.age); // βœ… 0 (int default)
System.out.println(s.active); // βœ… false (boolean default)
}
}
class Student {
String name; // defaults to null
int age; // defaults to 0
boolean active; // defaults to false
}
  • Instance variables always have a default, so you never get a β€œyou forgot to set this” error.
  • The downside: a stray 0 or null can slip through if you forgot to set it on purpose.
  • Local variables behave the opposite way, as we will see.

Output

null
0
false

🌐 Static variables: shared by all

For data that belongs to the class as a whole, add the static keyword. A static variable has just one copy, shared by every object. Change it anywhere and all objects see the new value, because there is only one value.

Use it for facts true for the group, not the individual:

  • A counter that tracks how many objects have been created.
  • A setting that should be the same for everyone, like a default currency.
  • A shared constant, like the number of legs on every dog.

This program creates three students, and the class keeps a single shared count of how many exist:

public class Main {
public static void main(String[] args) {
new Student();
new Student();
new Student();
System.out.println("Students created: " + Student.count); // βœ… 3
}
}
class Student {
static int count = 0; // shared by all objects, one copy
Student() {
count++; // every new object adds to the same count
}
}
  • There is only one count for the whole class.
  • Each new student runs the constructor, which adds 1 to that shared variable.
  • After three students, count is 3, no matter which object touched it.
  • You read it with the class name, Student.count, because it belongs to the class.

Output

Students created: 3

Access static through the class name

Because a static variable belongs to the class, you read it with the class name, like Student.count. An instance variable belongs to an object, so you read it through an object, like s1.name. Keep the two access styles separate in your head and your code stays clear.

πŸ“ Local variables: temporary helpers

A local variable is declared inside a method and lives only while that method runs.

  • It exists only during the one call that created it.
  • It vanishes the moment the method returns.
  • It is private to that method. Nothing outside can read it.

This method adds two numbers using a local helper variable, then returns the result:

class Calculator {
int add(int a, int b) {
int result = a + b; // local variable, exists only here
return result;
}
}
  • result is local, and so are the parameters a and b. Parameters count as locals too.
  • They appear when add starts and disappear when it returns. Each call gets fresh copies.
  • The big difference from fields: locals have no default value.
  • Use one before assigning it and your program will not even compile.

This code tries to read a local variable before giving it a value, and Java refuses:

int badAdd(int a, int b) {
int result; // ❌ declared but not assigned
return result + a; // ❌ compile error: result might not be initialized
}

To fix it, just assign before you read:

int goodAdd(int a, int b) {
int result = a + b; // βœ… assigned before use
return result;
}

Java does this to protect you. A field defaulting to 0 might hide a bug, but a local with no value would be pure garbage, so Java stops you early.

Local variables must be initialized

Instance and static variables get default values automatically (0, 0.0, false, null). Local variables do not. If you try to use a local variable before assigning it, Java gives a β€œvariable might not have been initialized” error. Always set a local variable before reading it.

πŸ—‚οΈ Where each variable lives, and how long

Where Java keeps each variable explains how long it lasts. Java uses two storage areas:

  • The heap holds objects. new Student() puts the object and its instance variables here. They live as long as the object is in use, then Java cleans them up.
  • The stack holds method calls. Each call gets a slot for its local variables. The slot appears on call, vanishes on return, and is reused by the next call.
  • Static variables live with the class, not on the heap or stack. One copy lasts the whole program.

So a local cannot β€œremember” anything between calls (its home is wiped each time), while an instance variable holds data for the whole life of its object.

🌍 A full worked example

Let’s tie instance and static together. Each Player has its own name and score (instance), while the class keeps a shared playerCount (static).

This program creates two players, gives each their own score, raises one score, then prints both players plus the shared count:

public class Main {
public static void main(String[] args) {
Player p1 = new Player("Alex");
Player p2 = new Player("Riya");
p1.score = 50; // βœ… only p1's score
p2.score = 80; // βœ… only p2's score
p1.score += 10; // βœ… p1 now 60, p2 untouched
System.out.println(p1.name + ": " + p1.score);
System.out.println(p2.name + ": " + p2.score);
System.out.println("Total players: " + Player.playerCount);
}
}
class Player {
String name; // instance: each player's own
int score; // instance: each player's own
static int playerCount = 0; // static: shared by all players
Player(String name) {
this.name = name; // set this object's name
playerCount++; // bump the one shared counter
}
}

Step by step:

  • Making p1 (β€œAlex”) sets p1.name and adds 1 to playerCount, now 1.
  • Making p2 (β€œRiya”) sets p2.name and adds 1 again, so playerCount is now 2.
  • p1.score becomes 50 and p2.score becomes 80. Independent, each player keeps its own.
  • Adding 10 to p1.score takes it to 60. p2.score stays at 80, untouched.
  • The shared playerCount is 2, and both players see that same number.

Output

Alex: 60
Riya: 80
Total players: 2

πŸ“Š The three kinds side by side

All three together, at a glance.

Feature Instance variable Static variable Local variable
Declared where In the class In the class, with static Inside a method
Belongs to Each object The class (shared) That one method call
How many copies One per object One for everyone One per call
Default value? Yes (0, false, null) Yes (0, false, null) No, must set it first
Lives in memory Heap, with the object With the class Stack, with the call
How long it lasts As long as the object Whole program Only while the method runs
Accessed by Object, like s1.name Class, like Student.count Just its name, inside the method

⚠️ Common Mistakes

A few slip-ups trip people up again and again.

Expecting local variables to have a default. Fields get filled in; locals do not.

// ❌ Wrong: count is never assigned, this will not compile
int total() {
int count;
return count + 1;
}
// βœ… Right: assign before you use it
int total() {
int count = 0;
return count + 1;
}

Expecting instance variables to be shared. Setting a field on one object does not change others. Instance variables are per-object and independent.

// ❌ Wrong assumption: setting one changes both
Player p1 = new Player("Alex");
Player p2 = new Player("Riya");
p1.score = 100;
// p2.score is still 0 here, not 100. They are separate.
// βœ… If you truly want one shared value, use static instead
class Player {
static int teamScore; // one value for the whole team
}

Shadowing a field with a local of the same name. When a parameter shares a field’s name, the parameter wins inside the method, so the field never changes. Fix it with this.

// ❌ Wrong: "name" here means the parameter, not the field
class Player {
String name;
void setName(String name) {
name = name; // assigns the parameter to itself, field stays null
}
}
// βœ… Right: this.name points clearly at the field
class Player {
String name;
void setName(String name) {
this.name = name; // field gets the parameter's value
}
}

Reading static through an object. It compiles, but it hides that the value is shared. Use the class name instead.

Player p = new Player("Alex");
System.out.println(p.playerCount); // ❌ misleading, looks per-object
System.out.println(Player.playerCount); // βœ… clear: it belongs to the class

βœ… Best Practices

Good habits for choosing the right kind.

  • Default to instance variables for object data. Name, age, balance, score, anything that differs per object. This is most of your data.
  • Use static only for truly shared data. A counter of all objects, a constant, or a setting that is the same for everyone.
  • Keep local variables for short-lived work. Temporary calculations inside a method that nobody else needs.
  • Always assign a local before you read it. Java will stop you anyway, so just set it up front and move on.
  • Use this when a parameter shadows a field. It removes any doubt about which one you mean.
  • Access static through the class name. Write Player.playerCount, not p.playerCount, so readers know it is shared.

🧩 What You’ve Learned

Great, that completes OOP basics. The key points:

  • βœ… An instance variable belongs to each object; every object gets its own independent copy.
  • βœ… A static variable uses static and is shared by all objects of the class, with one copy.
  • βœ… A local variable lives inside a method and disappears when the method ends.
  • βœ… Instance and static variables get default values (0, false, null); local variables get none and must be set first.
  • βœ… Instance variables live with the object on the heap, locals live with the call on the stack, and static lives with the class.
  • βœ… Read static through the class name (Student.count) and instance variables through an object (s1.name).

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What is true of an instance variable?

    Why: Each object gets its own copy of an instance variable, so they are independent.

  2. 2

    What does the static keyword do to a variable?

    Why: A static variable belongs to the class and is shared across all objects.

  3. 3

    Which kind of variable has NO default value?

    Why: Local variables must be initialized before use; instance and static variables get defaults like 0, false, and null.

  4. 4

    How should you access a static variable like count?

    Why: Static variables belong to the class, so access them through the class name.

πŸš€ What’s Next?

You now know the kinds of variables a class can hold. Next come constructors, the special methods that set up an object’s instance variables the moment it is created.

Java Constructors

Share & Connect