Skip to content
Java getting started 7 min read

Variables

A variable is a named container that holds a value in your program. Every piece of data you work with in Java — a player’s score, a user’s name, a loop counter — lives in a variable.

What Is a Variable?

Think of a variable as a labeled box: you give the box a name, tell Java what kind of thing it will hold (its type), and then put a value inside. In Java, you must declare a variable’s type before you use it — the compiler enforces this at compile time, which catches many bugs early.

int score = 100;          // integer variable
String playerName = "Alice"; // string variable
double temperature = 36.6;   // floating-point variable
boolean isActive = true;     // boolean variable

Declaring and Initializing Variables

Declaration tells Java the variable’s name and type. Initialization assigns it a value. You can do both on one line or separately.

// Declaration only — NOT yet usable (compiler error if you read it first)
int age;

// Initialization
age = 25;

// Declaration + initialization in one step (most common)
int count = 0;

Note: Local variables (inside methods) are NOT given a default value — you must assign one before reading. Instance variables get safe defaults (0, false, null).

Variable Naming Rules

Java has strict rules and strong conventions for naming variables.

RuleExample
Must start with a letter, _, or $_count, $price
Cannot start with a digit1score — illegal
Cannot be a Java keywordint as a name — illegal
Case-sensitiveage and Age are different
No spaces allowedmy score — illegal

Follow the Java naming conventions: variable names use lowerCamelCase (totalScore, firstName). Constants use UPPER_SNAKE_CASE (MAX_SIZE).

Types of Variables

Java classifies variables by where they are declared. There are three categories.

1. Local Variables

Declared inside a method (or block). They exist only while that method is executing and are destroyed when the method returns.

public class Counter {
    public void printDouble(int n) {
        int result = n * 2;   // local variable
        System.out.println(result);
    }
}
  • Must be initialized before use — no default value.
  • Cannot use access modifiers (private, public) on them.
  • Invisible outside the method.

2. Instance Variables (Non-Static Fields)

Declared inside a class but outside any method. Every object of the class gets its own copy.

public class Car {
    String model;    // instance variable
    int year;        // instance variable

    public void printInfo() {
        System.out.println(model + " (" + year + ")");
    }
}

public class Main {
    public static void main(String[] args) {
        Car c1 = new Car();
        c1.model = "Tesla";
        c1.year = 2024;

        Car c2 = new Car();
        c2.model = "Honda";
        c2.year = 2022;

        c1.printInfo(); // Tesla (2024)
        c2.printInfo(); // Honda (2022)
    }
}

Output:

Tesla (2024)
Honda (2022)

Each Car object holds independent copies of model and year — changing one does not affect the other.

Tip: Instance variables are stored in the heap alongside their object. They are automatically initialized to their default value (see table below) when the object is created.

3. Static Variables (Class Variables)

Declared with the static keyword. There is exactly one copy shared across all instances of the class.

public class Employee {
    static int companyCode = 1001;  // shared by all Employee objects
    String name;

    public Employee(String name) {
        this.name = name;
    }

    public void printDetails() {
        System.out.println(name + " — company: " + companyCode);
    }
}

public class Main {
    public static void main(String[] args) {
        Employee e1 = new Employee("Bob");
        Employee e2 = new Employee("Carol");

        Employee.companyCode = 2099;  // change via class name — affects all

        e1.printDetails(); // Bob — company: 2099
        e2.printDetails(); // Carol — company: 2099
    }
}

Output:

Bob — company: 2099
Carol — company: 2099

Quick Comparison

FeatureLocalInstanceStatic
Where declaredInside a methodInside class, outside methodInside class with static
Default valueNone (must initialize)Yes (0 / false / null)Yes (0 / false / null)
Memory locationStackHeap (per object)Method area (one copy)
Access viaVariable nameobjectRef.fieldClassName.field
LifetimeMethod callObject lifetimeProgram lifetime

Default Values

When you declare an instance or static variable without an explicit value, Java assigns a safe default:

TypeDefault
byte, short, int, long0
float, double0.0
char'\u0000' (null char)
booleanfalse
Any object / arraynull
public class Defaults {
    int x;
    boolean flag;
    String text;

    public static void main(String[] args) {
        Defaults d = new Defaults();
        System.out.println(d.x);     // 0
        System.out.println(d.flag);  // false
        System.out.println(d.text);  // null
    }
}

Output:

0
false
null

Variable Scope

Scope determines where a variable is visible in your code.

public class ScopeDemo {
    int instanceVar = 10;   // visible throughout the class

    public void method() {
        int localVar = 20;  // visible only inside this method

        if (true) {
            int blockVar = 30;  // visible only inside this if-block
            System.out.println(instanceVar + localVar + blockVar); // 60
        }
        // blockVar is NOT accessible here
    }
}

Warning: A local variable declared inside an inner block (like an if or for loop) is destroyed when that block ends. Attempting to access it outside causes a compile error.

The var Keyword (Java 10+)

Since Java 10, you can use var to let the compiler infer the type of a local variable. The variable is still strongly typed — var is just syntactic sugar.

var message = "Hello, Java!";   // inferred as String
var count = 42;                  // inferred as int
var list = new java.util.ArrayList<String>(); // inferred as ArrayList<String>

System.out.println(message);
System.out.println(count + 1);

Note: var only works for local variables with an initializer. You cannot use it for method parameters, return types, or fields. See the full var keyword page.

Constants with final

Add the final modifier to prevent a variable from being reassigned. By convention, final constants use UPPER_SNAKE_CASE.

public class Circle {
    static final double PI = 3.14159265358979;

    public static double area(double radius) {
        return PI * radius * radius;
    }

    public static void main(String[] args) {
        System.out.println(area(5)); // 78.53981633974483
    }
}

Trying to do PI = 3.0; after the assignment causes a compile error. Learn more on the final keyword page.

Under the Hood

Understanding how the JVM stores variables helps you write better code.

Stack vs Heap

  • Local variables (primitives and object references) live on the stack. Stack frames are created when a method is called and discarded when it returns — this is extremely fast (just moving a stack pointer).
  • Instance variables live in the heap alongside the object they belong to. Heap allocation is slightly costlier but objects can outlive the method that created them.
  • Static variables live in the Method Area (part of the heap since Java 8’s removal of PermGen). They are loaded when the class is loaded and live until the class is unloaded.

Primitive vs Reference

  • Primitives (int, double, boolean, …) store the actual value directly in the variable slot.
  • Reference types (any class, array, interface) store a pointer to the object on the heap. Assigning one reference variable to another copies the pointer, not the object — both variables then point to the same object.
int a = 5;
int b = a;  // b gets a copy of the value
b = 99;
System.out.println(a); // still 5

int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;     // arr2 points to the same array
arr2[0] = 999;
System.out.println(arr1[0]); // 999 — same object!

Output:

5
999

This distinction is why Java uses call by value for everything — but the “value” passed for objects is the reference itself.

See Data Types for a full breakdown of primitive vs reference types, and JVM Architecture for a deep dive into stack frames and heap organization.

  • Data Types — understand the full set of types a variable can hold
  • final Keyword — make variables immutable with final
  • static Keyword — share state across all instances with static variables
  • var Keyword — let Java 10+ infer local variable types automatically
  • JVM Architecture — see exactly how the stack and heap store your variables
  • Operators — manipulate variable values with Java’s operator set
Last updated June 13, 2026
Was this helpful?