ProgrammingJava Developer

How does the final mechanism work in Java — for variables, methods, and classes, and what unexpected effects can incorrect usage of this modifier cause?

Pass interviews with Hintsage AI assistant

Answer.

final in Java is used for:

  • Variables — becomes immutable after initialization;
  • Methods — cannot be overridden in subclasses;
  • Classes — cannot have subclasses.

Features and nuances:

  • final variable must be initialized at the declaration or in the constructor;
  • final reference does not allow changing the reference, but the object referenced can be modified (if it is not immutable!);
  • Inheriting from a final class (e.g., String, Math) is not possible;
  • Cannot override a final method, even if the class is inheritable.
final class A {} // cannot make class B extends A class Parent { final void foo() { } } class Child extends Parent { // void foo() {} // error: cannot override foo } final int COUNT = 10;

Tricky question.

Can you change the state of the object that a final variable refers to?

Answer: Yes, if it is not an immutable object. For example:

final List<String> names = new ArrayList<>(); names.add("Vasya"); // This is allowed — the object referenced is modified, but not the reference itself names = new ArrayList<>(); // Compilation error

Examples of real errors due to misunderstanding the nuances of the topic.


Story

In the logging system, a single final Logger was passed throughout the code, considering the object completely protected — but settings were changed through a public method, globally breaking the configuration.

Story

In a utility class, final fields of type List were made, and then attempts were made to return them for external use. External code quietly modified the contents of the list via the obtained reference — final does not protect against that at all.

Story

There was a task to extend an external API built on final classes. Because of them, it turned out to be impossible to make extensions, leading to duplicated logic and maintaining two independent branches of the product, complicating migrations.