In Java, a variable stores a value that can change while a program runs, whereas a constant stores a value that must not change after it has been set. Choosing the correct type and name makes code clearer and less error-prone.
Variables
A variable has a data type, a name, and (optionally) an initial value. The type tells Java what kind of data the variable can hold.
Variables, unlike constants, can have their value changed, but their data type must remain the same.
Declaring variables
int age; // declaration only double height = 1.82; // declaration + initialisation String name = "Jamie";
Variables can be declared first and assigned later, or declared and initialised in one step.
Primitive vs reference types
Java has two broad categories of types:
- Primitive types: byte, short, int, long, float, double, char, boolean.
- Reference types: classes and arrays (e.g. String, ArrayList, custom classes).
Primitive variables hold the value directly. Reference variables hold a reference (an address) to an object in memory.
The table below lists the built-in primitive types in Java and some of the most common reference types.
| Type | Category | Description | Example Value |
|---|---|---|---|
byte |
Primitive | Stores whole numbers from -128 to 127 | 42 |
short |
Primitive | Stores whole numbers from -32,768 to 32,767 | 1000 |
int |
Primitive | Stores whole numbers (typically used by default) | 25000 |
long |
Primitive | Stores large whole numbers (add L at the end) |
1000000000L |
float |
Primitive | Stores decimal numbers (add f at the end) |
3.14f |
double |
Primitive | Stores decimal numbers with higher precision | 3.14159 |
char |
Primitive | Stores a single character (enclosed in single quotes) | 'A' |
boolean |
Primitive | Stores true or false |
true |
String |
Reference | Stores a sequence of characters (text) | "Hello" |
String[2] |
Reference | Stores an array of multiple values of the same type (in this case an string with two positions) | {1, 2, 3} |
ArrayList<T> |
Reference | Resizable list (T would be replaced with a data type) |
new ArrayList<String>() |
Object |
Reference | The root type for all other classes in Java | new Object() |
Initialisation and assignment
int counter; counter = 0; // assignment counter = counter + 1; // reassignment String greeting = "Hello"; greeting = greeting + ", world!"; System.out.println(greeting);
Hello, world!
Type inference
From Java 10, you can use var for local variables when the type is obvious from the initialiser. This is
called local type inference.
This does not make Java dynamically typed—the inferred type is still fixed at compile time.
var sum = 0; // inferred as int var message = "Hi"; // inferred as String var values = new ArrayList<String>(); // inferred as ArrayList<String>
The use of var requires an initialiser value.
Static
Sometimes a variable in Java is declared with the static keyword.
A static variable belongs to the class rather than any specific
instance (object) of that class. This means there is only one shared copy of the variable,
and its value is kept even when methods are called multiple times or objects are created.
There is more on this in the article on classes.
Scope and lifetime
The scope of a variable is the region of code where it can be used. A variable declared
inside a block { ... } is only accessible within that block. Its lifetime ends when the block finishes.
int total = 0; { int temp = 5; total += temp; // ok } // System.out.println(temp); // error: temp is out of scope
Variables declared inside a subprogram only exist while that subprogram is running. When the subprogram finishes, those variables are removed from memory. These are known as local variables.
void displayMessage(){ String message = "Hello from inside the subprogram!"; System.out.println(message); } displayMessage(); // System.out.println(message); // error: message is not in scope
The variable message exists only while the subprogram
displayMessage is running. Once it finishes,
message is destroyed and cannot be accessed elsewhere.
If a variable needs to be used by several subprograms, it can be declared outside of all subprograms. Such variables are called global variables, although in Java they are usually represented as fields of a class.
public class Example { static int counter = 0; // class-level (global) variable static void increment(){ counter++; } static void showCounter(){ System.out.println(counter); } public static void main(String[] args){ increment(); increment(); showCounter(); // Output: 2 } }
In this example, counter is shared between the two subprograms
increment and showCounter.
Because it is declared outside of any subprogram and marked
static, its value is preserved for the lifetime of the program.
Constants
A constant is created using the final keyword. Once assigned, a final variable cannot be reassigned.
final double VAT_RATE = 0.20; // VAT_RATE = 0.25; // error: cannot assign a value to final variable
Class-level constants are typically
public static final so they can be accessed without creating an object.
public class Finance { public static final double STANDARD_VAT = 0.20; } System.out.println(Finance.STANDARD_VAT);
With reference types, final prevents reassignment of the reference, but the object itself may still be mutable.
final ArrayList<String> names = new ArrayList<>(); names.add("Alex"); // allowed: mutating the object // names = new ArrayList<>(); // error: cannot reassign final reference
Worked example
The short program below combines variables and a constant to calculate a discounted price with VAT added.
public class Prices { public static final double VAT = 0.20; public static void main(String[] args) { double originalPrice = 50.00; double discount = 0.10; // 10% double afterDiscount = originalPrice * (1.0 - discount); double finalPrice = afterDiscount * (1.0 + VAT); System.out.println("Final price: £" + finalPrice); } }
Final price: £54.0
