static and final are two of the most used Java modifiers. static makes a member belong to the class instead of each object; final stops a variable, method or class from being changed. Together they give you constants such as static final int TIMEOUT = 10.
static Keyword
public class Counter {
// static field: SHARED across ALL instances
private static int count = 0;
private int id;
public Counter() {
count++; // shared counter increments
id = count;// each object gets unique id
}
// static method: called on class, not object
public static int getCount() {
return count;
// Cannot use 'this' or access instance fields!
}
// static block: runs once when class is loaded
static {
System.out.println("Counter class loaded!");
}
// static nested class
public static class Helper {
public void help() { System.out.println("Helping!"); }
}
}
Counter.getCount(); // 0 — called on class
new Counter();
new Counter();
Counter.getCount(); // 2 — shared across instances
final Keyword
// 1. final VARIABLE: cannot be reassigned
final int MAX = 100;
// MAX = 200; // COMPILE ERROR
// 2. final REFERENCE: reference cannot change, object CAN
final List<String> list = new ArrayList<>();
list.add("Java"); // OK! Modifying object
// list = new ArrayList<>(); // COMPILE ERROR: can't reassign ref
// 3. final FIELD: must be assigned in constructor or declaration
public class Employee {
final String employeeId; // must be set in constructor
public Employee(String id) {
this.employeeId = id; // only place to set final field
}
}
// 4. final METHOD: cannot be overridden
public class Parent {
public final void template() { /* cannot override */ }
}
// 5. final CLASS: cannot be extended (e.g. String, Integer)
public final class Immutable { }
// class Child extends Immutable { } // COMPILE ERROR
Interview Questions
Can we override a static method?
No. Static methods are class-level, not object-level. What looks like overriding is 'method hiding' — the child class's version hides the parent's. No dynamic dispatch — which version runs depends on the REFERENCE type, not the object type.
What is the difference between final, finally, and finalize?
final: keyword for variables/methods/classes. finally: block in try-catch that always executes. finalize(): method called by GC before object is collected (deprecated since Java 9 and marked for removal since Java 18).
static and final Together: Constants
public final class Config {
public static final int DEFAULT_TIMEOUT_SECONDS = 10; // one shared, unchangeable value
public static final String BASE_URL = System.getProperty("baseUrl", "https://qa.example.com");
private Config() { } // no instances: utility class
}
Constants are static final, named in UPPER_SNAKE_CASE, and grouped in a class that can't be instantiated or extended.
Where You Use Them in a Test Framework
| Use | Keyword | Example |
|---|---|---|
| Timeouts, URLs, file paths | static final | Config.DEFAULT_TIMEOUT_SECONDS |
| Utility methods with no state | static | ScreenshotUtil.capture(driver, name) |
| Load configuration once | static block | static { props.load(...); } |
| Locators in a page object | private final | private final By loginButton = By.id("login"); |
| Driver per thread | static final ThreadLocal | private static final ThreadLocal<WebDriver> DRIVER = new ThreadLocal<>(); |
The one thing not to make plain static is the WebDriver itself: a single static driver is shared by every thread, which breaks parallel runs.