Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 208
Raj Avatar asked Sep 04 '13 07:09

Raj


People also ask

Why should we make class as final in immutable class?

By declaring immutable classes final, we impose a guarantee that malicious subclasses capable of changing the state of the object and violating assumptions that clients often make regarding immutability, are not a concern.

Does an immutable class need to be final?

No, it is not mandatory to have all properties final to create an immutable object. In immutable objects you should not allow users to modify the variables of the class. You can do this just by making variables private and not providing setter methods to modify them.

Are final fields immutable?

final means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g). Whereas immutable means that the object's actual value can't be changed, but you can change its reference to another one.

Why would one want to make fields immutable?

As Immutable objects cannot be modified, there is no need to copy or clone its instance if you want to share it.


2 Answers

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

like image 106
Damian Leszczyński - Vash Avatar answered Sep 30 '22 21:09

Damian Leszczyński - Vash


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.

like image 27
Peter Lawrey Avatar answered Sep 30 '22 21:09

Peter Lawrey