CodeGym /Courses /JAVA 25 SELF /Initializing static and final fields

Initializing static and final fields

JAVA 25 SELF
Level 15 , Lesson 3
Available

1. Static fields: how to initialize them?

A static field (static) belongs not to an object, but to the class as a whole. Its value exists as a single instance for all objects of that class. By analogy — it’s like declaring a “shared cashbox” for all employees of a company: it doesn’t matter who shows up, the cashbox is shared by everyone.

Initialization at declaration

The simplest and most common way to initialize a static field is to assign it a value right at the declaration:

public class User {
    private static int userCount = 0; // initialization right here

    // ... other code
}

Such a field will be initialized when the User class is first loaded into memory.

Initialization in a static block

Sometimes you need more complex initialization logic — for example, to load data from a file or perform calculations. In this case, use a static initialization block:

public class Config {
    public static String configPath;

    static {
        // This block will run ONCE when the class is loaded
        configPath = System.getenv("APP_CONFIG_PATH");
        if (configPath == null) {
            configPath = "/etc/app/default.conf";
        }
        System.out.println("Config path initialized: " + configPath);
    }
}

When is a static block executed?

  • On the first reference to the class (for example, when creating the first object or calling any static method/field).
  • It runs only once per class.

Accessing static fields

  • Access static fields via the class name: User.userCount.
  • You can also access them through an object, but that’s considered poor style (it confuses readers).

Example:

User u1 = new User();
User u2 = new User();
System.out.println(User.userCount); // correct
System.out.println(u1.userCount);   // works, but not recommended!

2. final fields: when and how to initialize them?

final is a modifier that says: “This field can be assigned only once, and then it won’t change.” After initialization, the field’s value becomes immutable: for an object — it’s its fixed property, and for a class (if the field is static) — a shared constant.

Use cases:

  • Constants (for example, PI).
  • A unique object identifier that must not change after creation.

Requirements for initializing final fields

Java has a strict rule: every final field must be initialized either at declaration or in every constructor of the class.

Initialization at declaration

public class Circle {
    public static final double PI = 3.1415926535; // class constant
    private final String id = "CIRCLE";           // instance constant
}

Initialization in a constructor

Sometimes the value of a final field is known only when creating an object:

public class User {
    private final int id;

    public User(int id) {
        this.id = id; // assign final field in the constructor
    }
}

Important: if a class has multiple constructors, the final field must be initialized in each of them!

Combined example

public class Token {
    private final String value;
    private final long timestamp;

    public Token(String value) {
        this.value = value;
        this.timestamp = System.currentTimeMillis();
    }
}

Compilation errors for incorrect initialization

If you forget to initialize a final field, the compiler won’t let the program build:

public class Broken {
    private final int x; // not initialized

    public Broken() {
        // x is not assigned!
    }
}
// Error: variable x might not have been initialized

3. Combination of static and final: declaring class constants

The trio public static final is very common. In Java this is how you declare class constants — values that are set once and do not change during program execution. These constants belong to the class as a whole and are the same for all its objects.

Syntax and example

public class MathUtils {
    public static final double PI = 3.1415926535;
    public static final String APP_NAME = "MyApp";
}

Explanation:

  • public — accessible everywhere.
  • static — belongs to the class, not to a particular object.
  • final — cannot be changed after initialization.

Usage

double area = MathUtils.PI * r * r;
System.out.println(MathUtils.APP_NAME);

Convention: constant names are usually written in UPPER_CASE_WITH_UNDERSCORES.

4. Code examples: ways to initialize static and final fields

Example 1: Simple class with a constant

public class Constants {
    public static final int DAYS_IN_WEEK = 7;
    public static final String COMPANY = "Daisy LLC";
}

Example 2: Static field initialized in a static block

public class AppConfig {
    public static final String DEFAULT_PATH;

    static {
        // You can perform complex logic
        String env = System.getenv("APP_PATH");
        if (env != null) {
            DEFAULT_PATH = env;
        } else {
            DEFAULT_PATH = "/usr/local/app";
        }
    }
}

Example 3: final instance field, initialization in constructor

public class User {
    private static int nextId = 1;
    private final int id;
    private String name;

    public User(String name) {
        this.id = nextId++;
        this.name = name;
    }

    public int getId() { 
        return id; 
    }
    public String getName() {
        return name; 
    }
    public void setName(String name) { 
        this.name = name; 
    }
}

Usage:

User u1 = new User("Ivan");
User u2 = new User("Maria");
System.out.println(u1.getId()); // 1
System.out.println(u2.getId()); // 2

Example 4: Error due to incorrect final-field initialization

public class BadExample {
    private final int number;

    public BadExample() {
        // number is not initialized!
    }
}
// Compilation error: variable number might not have been initialized

5. Best practices for working with static and final fields

Use public static final only for true constants

If a value may change in the future (for example, a list of employees), don’t make it final! Constants must be truly immutable.

public static final int MAX_USERS = 1000; // good
public static final String[] USERS = new String[100]; // bad!

Although the reference USERS won’t change, the contents of the array can be modified. This can lead to unexpected bugs.

Use static blocks for complex initialization

If a constant can’t be expressed with a simple assignment (for example, it requires computation or reading from a file), use a static block.

Don’t overuse static fields

Static fields are global variables. Having too many of them can lead to hard-to-catch bugs and complicated maintenance.

Don’t make mutable objects public static final

If an object is mutable, don’t make it public and final. That will expose its internals to everyone, and someone will inevitably take advantage of it.

6. Common mistakes when initializing static and final fields

Error #1: Uninitialized final field. If you forget to initialize a final field either at declaration or in all constructors, the compiler will report an error. For example, if a class has two constructors and you forget to assign a value to the final field in one of them — you’ll get an error.

Error #2: Changing the value of a final field. Attempting to change a final field after initialization will result in a compilation error.

public class Demo {
    private final int x = 5;
    public void change() {
        x = 10; // Error: cannot assign a value to final variable x
    }
}

Error #3: Public mutable static final fields. If you make a mutable object (String[], int[], etc.) public static final, any code will be able to change its contents. This breaks encapsulation and can lead to elusive bugs.

Error #4: Using non-static fields in a static block. You can’t access instance fields from a static block because they haven’t been initialized yet (and don’t exist at that stage at all).

Error #5: Unexpected initialization order. If you access static fields in a static block that are declared later in the code, they may not be initialized yet. Always declare static fields before static blocks if you plan to use them there.

1
Task
JAVA 25 SELF, level 15, lesson 3
Locked
Global active users counter 🌐
Global active users counter 🌐
1
Task
JAVA 25 SELF, level 15, lesson 3
Locked
Immutable student name on identity card 📝
Immutable student name on identity card 📝
1
Task
JAVA 25 SELF, level 15, lesson 3
Locked
Defining the application's default language ⚙️
Defining the application's default language ⚙️
1
Task
JAVA 25 SELF, level 15, lesson 3
Locked
Fundamental constants for calculations ⚛️
Fundamental constants for calculations ⚛️
Comments (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Hoist Level 38, San Diego, United States
13 May 2026
Output 3.14159 365