Why should fields be final in an immutable class?

A strategy for defining an immutable class says that

all fields must be final.

For ex:

private String name; 

Why should it be final?

So how do I not give it setter methods? It cannot be changed. Thanks.

+4
source share
6 answers

If you read

 private final String name; 

you know that the field is unchanging.

If you read

 private String name; 

you need to read the whole class to verify that it is not changed anywhere. That means a lot more work for you.

Now you can remember, having just written a class, that you did not add a setter, but after writing many other classes you will read your own class after six months, you will not remember reliably.

Even if it is not changed now, someone (perhaps himself) can change it later by adding code. However, you could assume that the meaning will not change.

In short, make this not final when you mean the value that needs to be changed, and make it final if you do not expect it to change. Do not leave it as it may / cannot be.


Now imagine that you are used to clearly understanding which fields can be changed and which cannot. This will save you a lot of work when reading the code of another code. But you find that you are reading code that is unclear and not final, does not mean that it has been changed, now it means that you need to check things, you usually did not need to check what another headache in trying to understand you really don't need code.


A simple example of how much more difficult it is to read the code to determine if the field is really final.

 public class A { static class B { private int x; } // some code 

All this looks great up to this point, no settings or even methods in B So, Bx is immutable right?

  static class C { public void update(B b, int x) { bx = x; // this really compiles } } } 

Alas, no, you need to read the entire class file.

You are much better off making every field you can final (which should have been IMHO by default) when you write the code, rather than leaving it for someone to figure out later.

+13
source
  • Saving the final field emphasizes the fact that it cannot be changed anywhere.
  • Self-documenting code, field must not be changed
  • The compiler will help you by indicating an error if you change the field elsewhere

So final helps in many ways to make an object immutable.

+3
source

The main reason (IMHO) is that when the field is final, it is guaranteed that it will be visible in other threads immediately after the constructor completes.

+1
source

It is good practice to make immutable fields final, even in other mutable objects.

Note that the private fields of one object can actually be accessed by other instances of the same class.

An object (class or instance) is unchanged if its internal state cannot be changed (reflection is not taken into account). Creating the final field ensures that the value (if it is primitive) or the reference (for non-primitives) cannot be changed.
For non-primitives, this does not automatically mean that the reference value is also immutable. This means that if your final field refers, for example, to a list, it is impossible to exchange the list, but add / remove values โ€‹โ€‹from it, thereby changing the state of the object.

To make the object immutable:

  • condition must be determined during construction and cannot change
  • This means that all fields that define the state must be final (you may have other auxiliary fields that are not related to the state, this is normal, but rarely).
  • It also means that all referenced objects must be immutable . Some objects, such as String, are already immutable; others, such as collections, can be wrapped to make them immutable ( Collections.immutableList|Set|Collection|... )
+1
source

Creating primitive final types guarantees immutability. However, making non-primitive objects finite, sometimes it makes no sense, since the final states of the object can be mutated. As Greg points out, it depends on the type of object in question

As an example that you showed, all properties are primitive, so the final meaning makes sense.

0
source

One of the advantages of declaring a final field is that it allows the compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.

0
source

Source: https://habr.com/ru/post/1500459/


All Articles