why fields should be final in immutable class? - java

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.

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.

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

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.

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|...)

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.

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.

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.

Related

Can I use setter method for a replacement of final variable In the following way

Most of us understand the consequences of shared mutability, and it is said that always prefer immutability(final modifier, set once and you can't change it) if you have a chance. I have seen few coding examples where People are actually making fields final or setters as private or even removing setters for a class (which can be DTO, Model or Entity class) and another class (a builder class which can set values once to that immutable class) is used to create and set fields of the Immutable class To ensure no other class is able to modify the state. Which seems a burden to me. SO I have come-up with this thought (below I am giving an example)
public class TestDataClass {
private String name;
public String getName() {
return name;
}
public void setName(Supplier<String> supplier) throws Exception {
if(Objects.isNull(name))
{this.name = supplier.get();return;}
throw new Exception("This field is immutable and already has a value "+this.name);
}
}
In this way either you can set values through setter like this objectOfTestDataClass.setName(() -> {return Perform_Desired_Logic;});
or
objectOfTestDataClass.setName(() ->"My Name"); if it is plain setter. Then also you dont have to create a bulder class or make setters private or omit setter method
In this way, I can get rid of variable initialization during Instantiation also once you set fields to become Immutable(I am not considering reflection).
I want your expert opinion to validate how legitimate is my thought, Can I consider this as Immutability? Am I missing something? in that case please correct me.
There are several things to note
Using a Supplier<String> instead of a String does not improve the code. There are only two cases, the intended case where the method is only executed once and the code of the supplier gets executed immediately and the erroneous case, where the supplier does not get executed, but where’s the sense in optimizing the erroneous case?
If a particular property supports being null, that approach fails to handle the case when it should be fixed to `null.
The API signature does not indicate that the class should be treated like immutable. Most readers will assume that it is mutable. So they may try to modify the object and not even notice the error if you’re going to remove the exception throwing statement, as said in a comment.
Immutable objects created by a builder are definitely completed and truly immutable once build. In contrast, your class allows the creator to forget setting some properties to fixed values, producing an actually mutable object.
Since instances of this class are not guaranteed to be immutable, they also do not have the guaranty to be thread safe that is usually associated with immutable objects.
What you wrote allows to not set more than one time a field of an object.
But it is not a way to create object with a fully initialized state as a constructor or a builder can provide.
So, if the client manipulates the object with a not complete or corrupted state, it could not work as expected.
Besides, providing setters that may be invoked by the clients at compile time but which the misuses would be known only at runtime (by throwing an exception) is not a friendly and good designed API.
Example of issue with an object that has a not complete state.
Take a Rectangle class.
It is composed of 4 mandatory information (height, weight, x and y coordinates).
These are represented by 4 instance fields :
int x, int y, int width, int height
Suppose the class provides an instance method boolean contains(Point p) to determinate if a Point (x, y coordinates) is included in it.
If you apply your method to value fields of this class, you may create Rectangle instances with incomplete/partial state.
The contains() method could not work. It should perform different checks and if a field is missing in Rectangle, it should may be even throw an exception.
Example of issue with an object which the state may be corrupted
If your object may be manipulated by multiple threads, using your way to value the fields of the object may set the object in an unexpected and inconsistent state.
Two threads may manipulate the object at the same time and changing two fields that should not be changed in this way.
To avoid it, you are forced to use explicit synchronization mechanisms for both reading and writing of fields.
Ii you use a constructor or a builder, you have not these problems as you get out of the box a complete, unmodifiable (de facto thread-safe) object with a clear API.

Best design approach for creating Immutable Class

I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.

Java Memory Model: Is it safe to create a cyclical reference graph of final instance fields, all assigned within the same thread?

Can somebody who understand the Java Memory Model better than me confirm my understanding that the following code is correctly synchronized?
class Foo {
private final Bar bar;
Foo() {
this.bar = new Bar(this);
}
}
class Bar {
private final Foo foo;
Bar(Foo foo) {
this.foo = foo;
}
}
I understand that this code is correct but I haven't worked through the whole happens-before math. I did find two informal quotations that suggest this is lawful, though I'm a bit wary of completely relying on them:
The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are. [The Java® Language Specification: Java SE 7 Edition, section 17.5]
Another reference:
What does it mean for an object to be properly constructed? It simply means that no reference to the object being constructed is allowed to "escape" during construction. (See Safe Construction Techniques for examples.) In other words, do not place a reference to the object being constructed anywhere where another thread might be able to see it; do not assign it to a static field, do not register it as a listener with any other object, and so on. These tasks should be done after the constructor completes, not in the constructor. [JSR 133 (Java Memory Model) FAQ, "How do final fields work under the new JMM?"]
Yes, it is safe. Your code does not introduce a data race. Hence, it is synchronized correctly. All objects of both classes will always be visible in their fully initialized state to any thread that is accessing the objects.
For your example, this is quite straight-forward to derive formally:
For the thread that is constructing the threads, all observed field values need to be consistent with program order. For this intra-thread consistency, when constructing Bar, the handed Foo value is observed correctly and never null. (This might seem trivial but a memory model also regulates "single threaded" memory orderings.)
For any thread that is getting hold of a Foo instance, its referenced Bar value can only be read via the final field. This introduces a dereference ordering between reading of the address of the Foo object and the dereferencing of the object's field pointing to the Bar instance.
If another thread is therefore capable of observing the Foo instance altogether (in formal terms, there exists a memory chain), this thread is guaranteed to observe this Foo fully constructed, meaning that its Bar field contains a fully initialized value.
Note that it does not even matter that the Bar instance's field is itself final if the instance can only be read via Foo. Adding the modifier does not hurt and better documents the intentions, so you should add it. But, memory-model-wise, you would be okay even without it.
Note that the JSR-133 cookbook that you quoted is only describing an implementation of the memory model rather than then memory model itself. In many points, it is too strict. One day, the OpenJDK might no longer align with this implementation and rather implement a less strict model that still fulfills the formal requirements. Never code against an implementation, always code against the specification! For example, do not rely on a memory barrier being placed after the constructor, which is how HotSpot more or less implements it. These things are not guaranteed to stay and might even differ for different hardware architectures.
The quoted rule that you should never let a this reference escape from a constructor is also too narrow a view on the problem. You should not let it escape to another thread. If you would, for example, hand it to a virtually dispatched method, you could not longer control where the instance would end up. This is therefore a very bad practice! However, constructors are not dispatched virtually and you can safely create circular references in the manner you depicted. (I assume that you are in control of Bar and its future changes. In a shared code base, you should document tightly that the constructor of Bar must not let the reference slip out.)
Immutable Objects (with only final fields) are only "threadsafe" after they are properly constructed, meaning their constructor has completed. (The VM probably accomplishes this by a memory barrier after the constructor of such objects)
Lets see how to make your example surely unsafe:
If the Bar-Constructor would store a this-reference where another thread could see it, this would be unsafe because Bar isnt constructed yet.
If the Bar-Constructor would store a foo-reference where another thread could see it, this would be unsafe because foo isnt constructed yet.
If the Bar-Constructor would read some foo-fields, then (depending on the order of initialization inside the Foo-constructor) these fields would always be uninitialized. Thats not a threadsafety-problem, just an effect of the order of initialization. (Calling a virtual method inside a constructor has the same issues)
References to immutable Objects (only final fields) which are created by a new-expression are always safe to access (no uninitialized fields visible). But the Objects referenced in these final fields may show uninitialized values if these references were obtained by a constructor giving away its this-reference.
As Assylias already wrote: Because in your example the constructors stored no references to where another thread could see them, your example is "threadsafe". The created Foo-Object can safely be given other threads.

Making final class variables static in GWT

In Java when a final field is assigned a constant value compile-time, it usually makes sense declaring it static. It saves overhead according to the relevant PMD rule.
Does it make any sense or difference doing it in GWT regarding the generated Javascript code?
If the variable is assigned when it is declared final, then yes, static makes a certain amount of sense, but there are cases where it should not be static:
public MyClassWithFinal {
private final String finalVar;
public MyClassWithFinal(String name) {
this.finalVar = name;
}
}
Another case: If the instance var is not a string or number constant, but requires running a constructor, that constructor may have side effects each time it is invoked, so running it only once is different than running it multiple times.
That said, GWT will inline/intern constant string values, so if you have multiple String fields all assigned to the same value, GWT will probably detect that and promote them all to static.
public final String constant = "Some Constant that really ought to be static";
GWT will notice that this is never assigned except when declared, and may even remove the field itself.
The best rule is to start with the best (i.e. most readable, most maintainable, most efficient) Java code, and to only break from that in cases where GWT requires something specific. This is not one of those cases: the compiler should perform the same basic optimizations no matter how you write this.
A field marked as final doesn't mean that it is immutable, only that its reference won't point to any other memory chunk. Therefore, it can only make sense to make a field static if it is really immutable, or if it is a primitive.
For instance, it's common to declare lists as final if you want to make sure that they will never point to a different list object, but the list itself can still be filled with data, cleared, filled again, etc. And of course, each object declaring such list does not mandatory want to share it among every instances.
private final List<...> list = new ArrayList<...>();
Final keyword is there to prevent you from doing mistakes, like setting to null a reference that should never change.

making a class immutable in java

To make a class immutable what I can do is:
1)Make class final
2)do not provide setters
3)mark all variables as final
But if my class has another object of some other class then , somone can change value of that object
class MyClass{
final int a;
final OtherClass other
MyClass(int a ,OtherClass other){
this.a = a;
this.other = other;
}
int getA(){
return a;
}
OtherClass getOther(){
return other;
}
public static void main(String ags[]){
MyClass m = new Myclass(1,new OtherClass);
Other o = m.getOther();
o.setSomething(xyz) ; //This is the problem ,How to prevent this?
}
}
A) Make the OtherClass immutable as well
or
B) Don't allow direct access to the OtherClass object, instead providing only getters to act as a proxy.
Edit to add: You could make a deep copy of OtherClass and return a copy rather than the original, but that generally isn't the type of behavior you would expect in Java.
Immutability is best considered from the perspective of the API user. So your object API needs to satisfy the following two conditions:
No way for an external user to change the value of the object
A guarantee that any time the user reads or makes use of the object's value in the future, it will get the same result
Important note: It is in fact OK to have mutable data inside an immutable object as long as it behaves as an immutable object from the perspective of the API user. Consider java.lang.String for example: although it is generally considered as the definitive immutable class, it does in fact have a mutable internal field for caching the hashCode (not many people know this!).
So to address your question, if you wish to contain another (mutable) object inside an immutable object then you typically need to do one or more of the following:
Guarantee that nobody else can change the value of the mutable object. Typically this means ensuring that no-one else can have a reference to the mutable object, so this is only usually possible if you create the object yourself rather than accept a reference from outside.
Take a defensive deep copy of the mutable object, and don't hand out references to the new copy. Only allow operations that read the new copy in the public API. If you need to hand out a reference to this object, then you need to take another defensive copy (to avoid handing out a reference to the internal copy).
Use an immutable wrapper for the mutable object. Something like Collections.unmodifiableList. This is useful if you want to hand out a reference to the internal mutable object but don't want to run the risk of it being modified.
All of these solutions are a bit hacky - a better solution overall is to avoid the use of mutable objects within immutable objects. In the long run it's asking for trouble because sooner or later a mutable reference will leak out and you will have an extremely hard to find bug. You are better moving towards a full hierarchy of immutable objects (the approach taken by languages like Scala and Clojure)
I assume OtherClass (by the way you say Other once) is meant to be a class you don't control, or which has to have a setter.
If you can't remove getOther, change it to getOtherView and return a read-only view of other. There will be wrappers for all the get methods, but no set ones.
Return deep clones from your getters. You may find this to be no easy task.
All the objects referenced in the immutable class should be immutable, or at least be encapsulated as private and making sure that they are not modified (not inside the methods of your class and definitely not from the outside). For instance, if you have this situation:
public class MyImmutable {
private MutableClass mutableObject;
}
... You can not provide the getMutableObject() method, because doing so will open the door for outside modifications, like this:
myImmutable.getMutableObject().setSomeAttribute(newValue);
As a special case of the above, all collections and/or maps should be made immutable, with the ummodifiableXXX() methods in the Collections class.
you cannot (reasonably) stop that in java. if you don't have control over the other class, there are ways to effectively get immutable behavior, but it can be very expensive in practice. basically, you must always return a copy of that class in any public method return values. (the jdk actually has this problem with the TimeZone class).
But If my class has another object of some other class then , somone
can change value of that object...
Java objects are not primitive. If you mark a primitive as final, then its value cannot be changed once it is assigned. However, object contents cannot be final, only object references can be final. So you cannot make an object in this way.
One solution might be abandoning all setter/mutator methods those could change the particular fields of the object and encapsulating them in a way that you can only access them, not change them.
It is possible to create the immutable class in java by following ways
1.Don't Provide setter methods.
2.Make all fields are as final and private.
3.Make Class as final.

Categories