Sobes.tech
Junior

In what cases can the final modifier be used in Java?

sobes.tech AI

Answer from AI

The final modifier in Java can be applied to:

  1. Variables:

    • Local variables: Their value is assigned once and cannot be changed after initialization.
    • Class fields: The value of the field is assigned either at declaration or in the constructor and then cannot be changed.
    • Method parameters: The parameter inside the method becomes a constant; it cannot be reassigned within the method body.

    Applying final to variables ensures:

    • Immutability: Guarantee that the value will not change.
    • Thread safety: final class fields are automatically visible to all threads after constructor completion without additional synchronization.
    • Compiler optimizations: The compiler can perform certain optimizations knowing that the value will not change.
  2. Methods:

    • A method declared as final cannot be overridden in subclasses.
    • This is useful for:
      • Preventing unwanted behavior changes: Ensures the method logic remains unchanged.
      • Encouraging composition: Promotes using composition instead of inheritance.
      • Possible compiler optimizations: The compiler can inline final method calls.
  3. Classes:

    • A class declared as final cannot have subclasses.
    • Applying final to a class is used for:
      • Creating immutable (unchangeable) classes: For example, wrapper classes for primitives (Integer, String).
      • Design protection: Prevents extension that could violate class invariants.
      • Enhanced security: Ensures class behavior cannot be altered through subclassing.
Application Description Advantages
final field Value is assigned once (at declaration or in constructor). Immutability, thread safety, optimizations.
final parameter Value cannot be changed inside the method. Clear signature, guarantee of parameter value immutability.
final method Cannot be overridden in subclasses. Prevents behavior change, encourages composition, optimizations.
final class Cannot have subclasses (inheritance is impossible). Class immutability, design protection, increased security.

Examples:

public class Example {
    // final class field
    private final String name;

    // final primitive field
    private final int id;

    // final, but can be a reference to different List objects until created
    // after object creation, the reference can be changed, but not the List itself
    private final List<String> items;

    // Compile-time constant
    public static final double PI = 3.14159;

    public Example(String name, int id) {
        this.name = name; // Assigning to final field name
        this.id = id;     // Assigning to final field id
        this.items = new ArrayList<>(); // Initializing final list field
    }

    // final method
    public final void printDetails() {
        System.out.println("Name: " + name + ", ID: " + id);
    }

    // Method with final parameter
    public void addItem(final String item) {
        // item = "new element"; // Compilation error: Cannot assign a value to final variable 'item'
        items.add(item);
    }
}

// final class
// public final class ImmutableClass {
//     private final int value;
//
//     public ImmutableClass(int value) {
//         this.value = value;
//     }
//
//     public int getValue() {
//         return value;
//     }
// }

// public class SubclassOfImmutable extends ImmutableClass { // Compilation error: Cannot inherit from final class
// }