Skip to main content
Advertisement

6.4 The static and final Keywords In Depth

static and final are among the most frequently used keywords in Java. Understanding their precise meaning and usage lets you write cleaner, more efficient code.

1. The static Keyword

When static is applied, that member belongs to the class itself, not to any particular instance. You can use it without creating an object.

1.1 Static Variables (Class Variables)

A static variable is shared by all instances. It is loaded into memory exactly once when the JVM loads the class.

public class Counter {
static int count = 0; // Shared by all objects
String name; // Each object has its own copy

Counter(String name) {
this.name = name;
count++; // Increment shared counter each time an object is created
}
}

Counter c1 = new Counter("First");
Counter c2 = new Counter("Second");
Counter c3 = new Counter("Third");

System.out.println(Counter.count); // 3 (access via class name!)

1.2 Static Methods

Methods callable without an instance. Cannot use this or access instance variables.

public class MathHelper {
public static int add(int a, int b) { return a + b; }
public static double circleArea(double radius) {
return Math.PI * radius * radius;
}
}

// No object needed!
int result = MathHelper.add(10, 20); // 30
double area = MathHelper.circleArea(5); // 78.53...

1.3 Static Initialization Blocks

Used for complex initialization of static variables. Runs exactly once when the class is first loaded by the JVM.

public class Config {
static final String DB_URL;
static final int MAX_CONNECTIONS;

static {
System.out.println("Loading config...");
DB_URL = System.getenv("DB_URL") != null
? System.getenv("DB_URL")
: "jdbc:mysql://localhost:3306/mydb";
MAX_CONNECTIONS = 10;
}
}

1.4 Static Imports

Use static members without the class name prefix.

import static java.lang.Math.*;

double result = sqrt(pow(3, 2) + pow(4, 2)); // Instead of Math.sqrt, Math.pow
System.out.println(result); // 5.0

2. The final Keyword

final means "cannot be changed anymore."

2.1 Final Variables (Constants)

Once assigned, the value can never change. By convention, constants use UPPER_CASE_WITH_UNDERSCORES.

public class Constants {
public static final double PI = 3.14159265358979;
public static final int MAX_SIZE = 100;
public static final String APP_NAME = "My Java App";
}

System.out.println(Constants.PI);
// Constants.PI = 3.14; // ❌ Compile error!

2.2 Final Methods

Prevents subclasses from overriding the method.

class Animal {
final void breathe() {
System.out.println("Inhaling oxygen."); // Cannot be overridden
}
void sound() { System.out.println("..."); }
}

class Dog extends Animal {
// @Override void breathe() { } // ❌ Compile error!
@Override void sound() { System.out.println("Woof!"); } // OK
}

2.3 Final Classes

Prevents any subclassing. Java's core classes like String and Integer are final for security and immutability guarantees.

final class ImmutablePoint {
private final int x;
private final int y;
ImmutablePoint(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
}
// class SpecialPoint extends ImmutablePoint { } // ❌ Compile error!

Pro Tip

Real-world patterns for static and final:

  1. Constants class pattern: Group related constants in a single final class.

    public final class HttpStatus {
    public static final int OK = 200;
    public static final int NOT_FOUND = 404;
    public static final int SERVER_ERROR = 500;
    private HttpStatus() {} // Prevent instantiation
    }
  2. Effectively final and lambdas: Local variables used inside lambdas must be final or effectively final (assigned only once). The compiler enforces this automatically.

  3. Performance tip: The JVM can inline static final primitive constants at compile time, making them extremely fast.

Advertisement