Variables
A variable is a named container for a value that lives in memory. In Java, every variable has a type that is fixed at compile time, a name (identifier), and a scope that determines where it can be accessed. Java is statically typed, so the compiler verifies that you only assign type-compatible values.
Declaring and Initializing
A declaration introduces a variable; initialization assigns it a first value. You can do both in one statement.
int count; // declaration only
count = 10; // initialization
double price = 19.99; // declaration + initialization
boolean active = true;
String name = "Ada";
Local variables must be assigned before they are read — the compiler enforces definite assignment. Fields, by contrast, receive default values automatically (0, 0.0, false, or null).
Warning: Reading a local variable before assigning it is a compile error, not a runtime surprise:
variable count might not have been initialized.
Kinds of Variables
Java distinguishes three categories based on where they are declared.
| Kind | Declared in | Lifetime | Default value? |
|---|---|---|---|
| Local | Inside a method/block | Until block exits | No (must assign) |
| Instance | Inside a class, non-static | Per object | Yes |
| Static (class) | Inside a class, static | Per class | Yes |
public class Account {
static int totalAccounts = 0; // static: shared across all instances
int balance; // instance: one per object
void deposit(int amount) { // amount is a parameter (local)
int fee = 1; // local variable
balance += amount - fee;
}
}
Scope and Shadowing
A variable is visible only within the block { ... } in which it is declared. Inner scopes can declare a variable with the same name as an outer field, which shadows the outer one.
public class Counter {
int value = 100;
void show() {
int value = 5; // shadows the field
System.out.println(value); // 5
System.out.println(this.value); // 100
}
}
Output:
5
100
Tip: Use
this.fieldto disambiguate when a parameter or local shadows a field — common in constructors and setters.
Constants with final
A final variable can be assigned exactly once. Combined with static, it defines a class-level constant, conventionally written in UPPER_SNAKE_CASE.
public class Circle {
static final double PI = 3.14159;
final int id; // blank final, set in constructor
Circle(int id) {
this.id = id; // legal: first and only assignment
}
}
Attempting to reassign a final variable is a compile error. Note that final makes the reference immutable, not the object it points to — final List<String> xs can still have elements added.
Naming Conventions
Identifiers must start with a letter, $, or _, followed by letters or digits. Java reserves keywords like class and int. Idiomatic Java uses:
camelCasefor variables and methods (firstName,totalCount)PascalCasefor classes (AccountManager)UPPER_SNAKE_CASEfor constants (MAX_SIZE)
int firstName; // good
int FirstName; // works but unconventional (looks like a class)
int 1stName; // compile error: cannot start with a digit
Local Variable Type Inference
Since Java 10, var lets the compiler infer a local variable’s type from its initializer. The variable is still strongly, statically typed — var is not dynamic typing.
var message = "hello"; // inferred String
var numbers = new int[]{1, 2, 3}; // inferred int[]
var total = 0L; // inferred long
var requires an initializer and works only for locals, not fields or method parameters.
Best Practices
- Declare variables in the narrowest scope that works, close to first use.
- Initialize at the point of declaration whenever possible.
- Prefer
finalfor variables that should not change — it documents intent and prevents bugs. - Use meaningful names; avoid single letters except for loop counters.
- Reach for
varwhen the type is obvious from the right-hand side, not to hide complex types.