Skip to content
Dev Dump

🎯 Static Keyword in Java: Complete Guide

Understanding static is critical for Java interviews because it intersects with:

  • Class loading and initialization
  • Memory management and garbage collection
  • Method behavior and polymorphism
  • Utility class design and patterns
  • Performance optimization

πŸ’‘ Interview Focus: Static tests your understanding of class vs instance behavior, memory management, and object-oriented design principles.

  • Allocated once during class loading, not per object
  • Shared across all instances of the class
  • Accessible without creating an object
TypePurposeExample
Static VariablesShared state across instancespublic static int counter = 0;
Static MethodsUtility behaviorpublic static int add(int a, int b)
Static BlocksConfiguration at class load timestatic { /* initialization */ }
Static Nested ClassesLogically grouped helperspublic static class Builder
Static ImportsImport static membersimport static java.lang.Math.PI;

ConceptBehavior
Memory LocationStored in Method Area (part of Metaspace in modern JVMs)
GC EligibilityLives as long as the class remains loaded in JVM
RiskHolding large static references may lead to memory leaks
InitializationWhen class is first loaded by ClassLoader
CleanupWhen ClassLoader is garbage collected

⚠️ Warning: In long-running applications (e.g., servers), a static reference to unused objects = memory leak risk.

public class MemoryExample {
// Static variable - allocated once when class loads
private static final List<String> staticCache = new ArrayList<>();
// Instance variable - allocated for each object
private String instanceData;
static {
// Static block - runs once during class loading
staticCache.add("Item 1");
staticCache.add("Item 2");
}
}

public class Counter {
private static int count = 0; // Shared across all instances
private int instanceId;
public Counter() {
instanceId = ++count; // Increment shared counter
}
public static int getTotalCount() {
return count; // Access static variable
}
public int getInstanceId() {
return instanceId;
}
}
// Usage
Counter c1 = new Counter(); // count = 1
Counter c2 = new Counter(); // count = 2
System.out.println(Counter.getTotalCount()); // 2
public class MathConstants {
public static final double PI = 3.14159;
public static final double E = 2.71828;
public static final int MAX_ITERATIONS = 1000;
// Private constructor to prevent instantiation
private MathConstants() {}
}
// Usage
double area = MathConstants.PI * radius * radius;
public class Configuration {
private static final Properties config = new Properties();
static {
try (InputStream input = Configuration.class
.getClassLoader()
.getResourceAsStream("config.properties")) {
if (input != null) {
config.load(input);
}
} catch (IOException e) {
throw new RuntimeException("Failed to load config", e);
}
}
public static String getProperty(String key) {
return config.getProperty(key);
}
}

public class StringUtils {
// Private constructor to prevent instantiation
private StringUtils() {}
public static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
public static String reverse(String str) {
if (str == null) return null;
return new StringBuilder(str).reverse().toString();
}
public static String capitalize(String str) {
if (isEmpty(str)) return str;
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
}
// Usage
String result = StringUtils.capitalize("hello"); // "Hello"
public class ConnectionFactory {
private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/mydb";
private static final String DEFAULT_USER = "root";
private static final String DEFAULT_PASSWORD = "password";
public static Connection createConnection() {
return createConnection(DEFAULT_URL, DEFAULT_USER, DEFAULT_PASSWORD);
}
public static Connection createConnection(String url, String user, String password) {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException("Failed to create connection", e);
}
}
}
// Usage
Connection conn = ConnectionFactory.createConnection();

public class DatabaseConnection {
private static Connection connection;
static {
try {
// Load driver
Class.forName("com.mysql.cj.jdbc.Driver");
// Initialize connection
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb",
"username",
"password"
);
System.out.println("Database connection established");
} catch (Exception e) {
System.err.println("Failed to initialize database: " + e.getMessage());
}
}
public static Connection getConnection() {
return connection;
}
}
public class ComplexInitialization {
private static final Map<String, String> config = new HashMap<>();
private static final List<String> cache = new ArrayList<>();
// First static block
static {
System.out.println("First static block executed");
config.put("app.name", "MyApp");
config.put("app.version", "1.0.0");
}
// Second static block
static {
System.out.println("Second static block executed");
cache.add("item1");
cache.add("item2");
}
// Third static block
static {
System.out.println("Third static block executed");
// Final initialization
config.put("cache.size", String.valueOf(cache.size()));
}
}

public class OuterClass {
private static String outerStaticField = "Outer Static";
private String outerInstanceField = "Outer Instance";
// Static nested class
public static class StaticNestedClass {
private String nestedField = "Nested Field";
public void display() {
System.out.println("Accessing outer static field: " + outerStaticField);
// Cannot access outerInstanceField - no outer instance reference
}
public static void staticMethod() {
System.out.println("Static method in nested class");
}
}
// Instance method to demonstrate usage
public void createNestedInstance() {
StaticNestedClass nested = new StaticNestedClass();
nested.display();
}
}
// Usage
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
OuterClass.StaticNestedClass.staticMethod();

πŸ—οΈ Static Nested Class with Builder Pattern

Section titled β€œπŸ—οΈ Static Nested Class with Builder Pattern”
public class Person {
private final String name;
private final int age;
private final String email;
private Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public static class Builder {
private String name;
private int age;
private String email;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Person build() {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name is required");
}
return new Person(name, age, email);
}
}
public static Builder builder() {
return new Builder();
}
}
// Usage
Person person = Person.builder()
.name("John Doe")
.age(30)
.email("john@example.com")
.build();

class Parent {
static void display() {
System.out.println("Parent static method");
}
void instanceMethod() {
System.out.println("Parent instance method");
}
}
class Child extends Parent {
static void display() {
System.out.println("Child static method");
}
@Override
void instanceMethod() {
System.out.println("Child instance method");
}
}
public class StaticInheritance {
public static void main(String[] args) {
Parent parent = new Parent();
Child child = new Child();
Parent polymorphic = new Child();
// Static methods - resolved at compile time
parent.display(); // "Parent static method"
child.display(); // "Child static method"
polymorphic.display(); // "Parent static method" (reference type matters)
// Instance methods - resolved at runtime
parent.instanceMethod(); // "Parent instance method"
child.instanceMethod(); // "Child instance method"
polymorphic.instanceMethod(); // "Child instance method" (object type matters)
}
}

public class StaticPitfalls {
private String instanceField = "Instance Field";
private static String staticField = "Static Field";
public static void staticMethod() {
// ❌ Bad: Cannot access instance field from static method
// System.out.println(instanceField);
// βœ… Good: Can access static field
System.out.println(staticField);
}
public void instanceMethod() {
// βœ… Good: Can access both static and instance fields
System.out.println(instanceField);
System.out.println(staticField);
}
}
public class ExecutionOrder {
static {
System.out.println("Static block 1");
}
private static String field = initializeField();
static {
System.out.println("Static block 2");
}
private static String initializeField() {
System.out.println("Field initialization");
return "Field Value";
}
public static void main(String[] args) {
System.out.println("Main method");
}
}
// Output:
// Static block 1
// Field initialization
// Static block 2
// Main method

// βœ… Good: Utility methods
public class MathUtils {
public static double calculateArea(double radius) {
return Math.PI * radius * radius;
}
}
// βœ… Good: Constants
public class Constants {
public static final int MAX_RETRY_ATTEMPTS = 3;
public static final String DEFAULT_ENCODING = "UTF-8";
}
// βœ… Good: Factory methods
public class ConnectionFactory {
public static Connection createConnection() {
// Factory logic
return new Connection();
}
}
// ❌ Bad: Stateful operations
public class UserService {
private static User currentUser; // Bad - shared state
public static void setCurrentUser(User user) {
currentUser = user; // Thread safety issues
}
}
// βœ… Good: Instance-based approach
public class UserService {
private User currentUser;
public void setCurrentUser(User user) {
this.currentUser = user;
}
}