Final Instance Variable
- If a variable's value varies from object to object, it is an instance variable.
- A separate copy of an instance variable exists for every object.
- Instance variables get default values from the JVM if not explicitly initialized.
Example:
class Test {
int x; // instance variable
public static void main(String... args) {
Test t = new Test();
System.out.print(t.x); // output: 0 (default value)
}
}
Where you may initialize a final instance variable:
- At the point of declaration: final int x = 10;
- Inside an instance initializer block
- Inside every constructor (so the field is definitely assigned before construction finishes)
Examples:
// 1) At declaration
class Test {
final int x = 10;
}
// 2) Instance initializer
class Test {
final int x;
{ // instance block
x = 10;
}
}
// 3) Constructor
class Test {
final int x;
Test() {
x = 10;
}
}
Invalid: attempting to assign a final instance field outside the above places (e.g. inside a static method) will cause a compile error: cannot assign a value to final variable.
Final Static Variables
If a value is common to all objects, declare it as a static variable (single copy shared by the class).
class Test {
static int x;
public static void main(String... args) {
System.out.print(x); // output: 0 (default for static int)
}
}
Places to initialize final static:
- At the time of declaration: final static int X = 10;
- Inside a static initializer block: static { X = 10; }
// Valid
class Test {
final static int X = 10;
}
// Valid via static block
class Test {
final static int X;
static {
X = 10;
}
}
// Invalid: assigning final static from instance method -> compile-time error
class Test {
final static int X;
public void m() {
X = 10; // compile error: cannot assign a value to final variable X
}
}
Final Local Variables
Local variables are declared in methods/blocks/constructors. JVM does not give default values — they must be initialized before use. The only modifier allowed for locals is final (access modifiers are not valid).
Key points:
- If a local variable is declared but not used, initialization is not required (but if it is used it must be definitely assigned before use).
- If a local variable is declared final, it still only needs to be assigned before use; it can be left unassigned if never used.
- Formal parameters (method parameters) are local to the method and can also be declared final — that prevents reassignment inside the method.
Examples:
// Uninitialized local used => compile error
class Test {
public static void main(String... args) {
int x;
System.out.print(x); // compile-time error: variable x might not have been initialized
}
}
// OK: local declared but never used
class Test {
public static void main(String... args) {
int x;
System.out.print("Hello"); // prints Hello
}
}
// final local: must be assigned before use (or can remain unassigned if never used)
class Test {
public static void main(String... args) {
final int x;
System.out.print("Hello"); // OK if x is never used
}
}
// final parameters: cannot be reassigned inside method
class Test {
public static void m(final int x, final int y) {
// x = 30; // compile-time error
// y = 50; // compile-time error
System.out.print(x + " --- " + y);
}
}
Summary
- Final instance: must be initialized at declaration, instance block or in constructor.
- Final static: must be initialized at declaration or in static block (before class loading completes).
- Final local: must be assigned before use (or can remain unassigned if never used); only modifier allowed for locals is final.