Java Variables

June 20, 20264 min readUpdated 8/20/2026

A variable is a named box that holds a value of a declared type. That definition sounds trivial and it is, but three things about variables in Java are not: the type is fixed, where you declare one decides how long it lives, and Java has three distinct kinds that behave differently.

Declaring and assigning

A declaration gives the box a type and a name. An assignment puts a value in it. You can do both at once, which you usually should.

int age = 30;                    // declare and assign together
String name = "Folau";
double balance = 1250.75;
boolean active = true;

int score;                       // declare now
score = 95;                      // assign later

score = 100;                     // reassigning is fine — the old value is gone

The = is an assignment operator, not a claim of equality. Read score = 95 as "put 95 into score", never as "score equals 95". Comparing for equality is ==, and mixing the two up is a real bug — Operators covers it.

Two rules the compiler enforces, both worth meeting now:

int count = 5;
// count = "five";        // will not compile: the type is part of the variable, permanently

int total;
// System.out.println(total);   // will not compile: variable total might not have been initialized

That second error is Java protecting you from reading a box before anything was put in it. Note that it applies to local variables only — and the next section is why.

The three kinds

Where you declare a variable determines its lifetime, its default value, and who can see it.

public class Account {

    static int accountsCreated = 0;   // 1. static — one copy, shared by the whole class

    private String owner;             // 2. instance — one copy per object
    private double balance;

    public Account(String owner) {
        this.owner = owner;
        accountsCreated++;
    }

    public void deposit(double amount) {
        double newBalance = balance + amount;   // 3. local — exists only in this method
        balance = newBalance;
    }
}
KindDeclaredLivesDefault if unassigned
Localinside a method or blockuntil the method returnsnone — the compiler makes you assign it
Instancein the class, no staticas long as the object does0, false, or null
Staticin the class, with staticas long as the program does0, false, or null

Those defaults are a common source of surprise. An instance field you forgot to set is not an error — it is silently null, and you find out when something calls a method on it. A local variable you forgot to set is a compile error. The compiler is stricter about locals precisely because it can be.

Scope: where a variable is visible

A variable exists from its declaration to the closing brace of the block containing it. Outside that block, the name does not exist.

void demonstrate(boolean flag) {
    int outer = 1;

    if (flag) {
        int inner = 2;
        System.out.println(outer);   // fine — outer is still in scope
    }

    // System.out.println(inner);    // will not compile: cannot find symbol
}

This catches people most often with loops, where the counter is scoped to the loop:

for (int i = 0; i < 3; i++) {
    System.out.println(i);
}
// System.out.println(i);            // will not compile: i died with the loop

int found = -1;                      // declare outside if you need it after
for (int i = 0; i < 3; i++) {
    if (i == 2) found = i;
}
System.out.println(found);           // 2

Keeping scope tight is a habit worth forming early: a variable declared in the smallest block that needs it cannot be accidentally used, reused, or left holding a stale value.

var, and when not to use it

Since Java 10, you can write var for a local variable and let the compiler work out the type from the right-hand side.

var message = "hello";                       // String
var count = 42;                              // int
var scores = new HashMap<String, Integer>(); // HashMap<String, Integer>

This is not dynamic typing. message is a String permanently, and assigning an int to it will not compile. You have skipped writing the type, not skipped having one.

var earns its place when the type is long and already obvious from the right-hand side — that HashMap line would otherwise repeat itself. It hurts when the right-hand side is a method call, because the reader now has to go and look up what the method returns:

record Customer(String name) { }

Customer lookup(String id) {
    return new Customer("Folau");
}

void call() {
    var a = lookup("c-1");        // what is a? You cannot tell without leaving this line.
    Customer b = lookup("c-1");   // clearer, and one word longer
}

The rule: use var when it removes noise, not when it removes information. It only works on locals — never on fields, parameters or return types, where the type is part of a contract someone else reads.

Naming

Java's conventions are near-universal and every team expects them:

  • camelCase for variables and methods — accountBalance, not account_balance.
  • UPPER_SNAKE_CASE for constants — static final int MAX_RETRIES = 3;
  • Names that say what the thing is. d costs the next reader thirty seconds; daysSinceLastLogin costs you nothing.

Loop counters (i, j) are the accepted exception, because their scope is three lines and the convention is older than Java.

Next

Every variable needed a type, and so far you have seen int, double, boolean and String without explanation. Data types is next: the eight primitives, what each one costs, and the two that will surprise you.