Raj
Raj

Reputation: 702

why fields should be final in immutable class?

Strategy for defining immutable class says that

all the fields should be final.

For ex:

private String name;

Why does it have to be final?

Since I am not giving setter methods for it? It can't be changed. Thanks.

Upvotes: 11

Views: 5867

Answers (7)

gauti
gauti

Reputation: 11

JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.

This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.

Upvotes: 0

Peter Walser
Peter Walser

Reputation: 15706

It's good practice to make immutable fields final, even on otherwise mutable objects.

Note that private fields of one object in fact CAN be accessed by other instances of the same class.

An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count). Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.

For an object to be immutable:

  • The internal state must be determined upon construction and can never change
  • This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
  • This also means that all refernced 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|...)

Upvotes: 1

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

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

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533472

If you read

private final String name;

you know the field is immutable.

If you read

private String name;

you have to read the entire class to check it is not changed anywhere. This is means much more work for you.

You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.

Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.

In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.


Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.


A simple example of how much harder it is to read code to determine if a field is effectively final.

public class A {
    static class B  {
        private int x;
    }

    // some code

This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?

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

Oops no, you have to read the whole class file.

It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.

Upvotes: 21

Sajith Silva
Sajith Silva

Reputation: 823

Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question

As the example you showed, all properties are primitive hence final keword make sense.

Upvotes: 0

The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.

Upvotes: 4

Narendra Pathai
Narendra Pathai

Reputation: 41935

  • Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
  • Self documenting code the the field should not be changed
  • Compiler will help you by giving error if you change the field somewhere else

So final helps in many ways for making object Immutable.

Upvotes: 3

Related Questions