I have doubt a doubt regarding making an immutable class.
As per the java docs.
I made the class final( no one can extend)
field are private.
no setter function.
If fields are mutable then send a cloned copy of the field.
My doubt is that its compulsory to make a field of my class as final?
If there are no setter methods (and presumably no other methods to affect the fields' values) and the fields themselves are private, marking them as final is somewhat redundant.
Having said that - its a good defensive practice which many projects' standards follow.
Although as many say its not mandatory to mark the fields as final I would say atleast in one case that I can think of you need to mark the fields as final and that is in the case if you want to make your immutable class thread safe.
According to Java memory model:-
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
JLS final thread safety
So if you have an immutable class with instance variables which you initialize in constructor as non final variables then there is no guarantee of thread safety as the writes to the non final variables may not be visible to other threads even though the constructor has fully run ( Note recreating this is very difficult as this may occur in a highly concurrent application)
Immutable = not changeable. So making properties final is a good idea. If not all properties of an object are protected from being changed I wouldn't say the object is immutable.
BUT an object is also immutable if it doesn't provide any setters for it's private properties.
An immutable object will never change, but anything that it refers to might change.
Deep immutability is much stronger: neither the base object nor any object you can navigate to from it will change.
Related
What is the benefit of making fields private while creating an immutable class?
I have seen why while creating immutable class, fields are declared as private? but I didn't get understand anything from this post.
Can anybody please explain me the same?
The best way to explain is with an example:
public class Immutable {
private final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Here we have a properly encapsulated, immutable class. Nothing can change the state (modulo nasty reflective tricks).
Now lets JUST change the access on the field:
public class Immutable {
public final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Note we are still making the defensive copy in getState ... as before ... but now someone can do this:
Immutable mu = new Immutable();
mu.state[1] = 'o';
... and our supposedly immutable object's state has changed.
That is ONE reason why it is a good idea to keep the fields private. (Obviously, this only applies to field whose types are mutable reference types.)
A SECOND reason is encapsulation. Declaring fields as private hides implementation details, which reduces the risk of unwanted cross-coupling. If I don't do this, then I (or some other programmer) might be tempted to write code that depends on the internals of Immutable. That is going to lead to problems if I need to change them; e.g. changing the type of state to String. Problems as in "lots more code to check / change".
A THIRD reason is that non-private (and particularly public) fields can be an impediment to subclassing. If I declare a field as public then, the I can't undeclare it in a subclass. If I want to hide the field or modify the behavior of the field in a subclass (by overriding) ... I can't. By contrast, if the field is private and access is via instance methods, I can override those methods in subclasses. Or I can choose to not use the field at all.
The only reason for making final fields private is binary compatibility, and this actually holds true irrespective of whether the containing class is immutable or not.
A class C is said to offer binary compatibility to classes X and Y
that use class C if class C can be refactored without having to
recompile classes X and Y.
You only need to worry about binary compatibility if you are developing a library to be used by software that is written by others and therefore you have no control over. If you are in this situation, then you pretty much have to use full encapsulation, which means that you have to make all fields private and only access them via getters.
However, in the vast majority of cases, what we are developing is top-layer, self-contained application software, not libraries to be used by others. So, in the vast majority of cases, there is no good reason to make final fields of immutable classes private, it is just a widely held misconception. In a top-layer, self-contained application scenario you can always refactor everything and your IDE will accordingly refactor all references, so immutable classes do not need encapsulation.
Some of the answers suggest that if a field is not private, and it points to a mutable object, then someone might go and modify that mutable object, which is of course correct, but then we go into the philosophical question of what really is an immutable object. Can an object still be called immutable if it contains mutable objects? Is the mutability of an object dependent on the mutability of objects that it contains?
My rule is as follows:
There are two kinds of fields: contained and referenced, which can otherwise be thought of as owned and unowned. As an example, think of an Employee class: the name of the employee is contained/owned by the class, since each employee has their very own name. However, the Employee class may also contain a reference to a Department class, and of course each employee does not have their very own department, so the department is a referenced/unowned field.
A contained/owned field like Employee.name must of course be final and immutable in order for the owning class (Employee) to be immutable. Such a field does not need to be private, unless we are aiming for binary compatibility.
A referenced/unowned field like Employee.department also needs to be final if the referring class (Employee) is to be immutable, but it does not have to be immutable, and its immutability does not affect the immutability of the referring class. Even in this case, (and unless we are aiming at binary compatibility,) a referenced/unowned field generally does not need to be private, because there is still no issue of encapsulation: we are not going to be making a defensive copy of an employee department, that would be nonsensical.
So, unless we are aiming for binary compatibility, then both in the case of contained/owned immutable fields and referenced/unowned fields (which can be either mutable or immutable,) the fields can stay public final and everything will be fine.
final class A{
final List l = new ArrayList();
}
Suppose you have list, and you made this list as final it's reference not modified at all.
But this list is easily accessible to outer classes and they are easily modify it's contents.
so prevent that we have to add private access specifier.
An object that is referred to by a public final reference-type field can still be modified through that field. (What you can't do is change the field to refer to a different object.)
To disallow unwanted modifications, you need to make the field private.
public fields can be accessed from any class anywhere and modified. But making fields private and final and using constructor injection / defensive copies, you ensure that the class is completely immutable.
Non-private fields may still be read-accessed - and if that field is an object, mutable operations on that object may be invoked.
Making the fields private will prevent this possibility.
If you'll use public field other objects will be able to change state of your "almost-immutable" object which will break encapsulation and make it a mutable object.
I have read and have always been told that immutable classes must be final . but i was wondering if it is possible to have a non final class object as immutable one.
in this link (Why would one declare an immutable class final in Java?) what if the immutable class methods are final and cannot be overriden . And if all the members of the class are final, then also the object of that class can be immutable( unless they reference to a mutable object). Please tell me if am wrong and get ticked :)
If you can extend an immutable class (which means it's not final), you can add mutable properties to the sub-class, which would make your sub-class mutable, and therefore the base class would also be mutable, since it can have mutable sub-classes.
An immutable class doesn't necessarily need to be final, but you need to prevent it from being subclassed, e.g. by not having public or protected constructors.
For example, Guava's ImmutableList class isn't final, but it is immutable, as described in the Javadoc.
For creating immutable class it is not mandatory to mark the class as final.
Let me take one of such example from java classes itself "BigInteger" class is immutable but its not final.
Actually Immutability is a concept according to which ones the object created then it can not be modified.
Let's think from JVM point of view, from JVM point of view all threads must share the same copy of the object and it is fully constructed before any thread accesses it and the state of the object doesn't change after its construction.
Immutability means there is no way yo change the state of the object once it is created and this is achieved by three thumb rules which makes the compiler to recognize that class is immutable and they are as follows :-
all non private fields should be final
make sure there is no method in the class that can change the fields of the object either directly or indirectly
any object reference defined in the class can't be modified outside from the class
For more information refer to the below URL
http://javaunturnedtopics.blogspot.in/2016/07/can-we-create-immutable-class-without.html
How does the JVM handle final variables differently under the hood?
There is at least one section in the JVM specification about final's impact on the memory model, and it is quite important for multi-threaded code:
final fields of an object allow "safe publication":
When a constructor exits, all final fields must be visible to all threads.
The fields on any object accessed via a final reference are also guaranteed to be at least as up to date as when the constructor exits.
Taken together, this means that immutable objects (ones where all fields are final and are either primitives or references to immutable objects) can be concurrently accessed without synchronization. It is also safe to read "effectively immutable" objects (ones whose fields aren't actually final, but in practice never change) via a final reference.
Conversely: If your object is accessed by multiple threads, and you don't declare its fields final, then you must provide thread-safety by some other means.
But note that the JVM does not enforce actual finality: You can re-assign values using reflection (which of course undermines the safe publication).
Recently I attended an interview.
I was asked how you can make a class Immutable.
I told him the answer.
But then he asked me why the fields are final?
I answered so that the user doesn't accidentally change the value of the field and it will give compiler error if he does so.
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
I was not able to answer. He told there is a reason behind that.
Can somebody explain?
From Effective Java:
Make all fields final. This clearly expresses your intent in a manner that is enforced by the system. Also, it is necessary to ensure correct behavior if a reference to a newly created instance is passed from one thread to another without synchronization, as spelled out in the memory model.
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
Only getter methods do not ensure that a class is immutable. If you expose the internal state than a client can change the class's state.
Immutable means that you can not change an objects state once it is created.
Making all fields final and providing only getters will not make it immutable out of the box. Imagine the following code:
public class MyString {
private final char[] content;
public MyString(String str){
this.content = str.toCharArray();
}
public char[] getContent(){
return this.content; // internal state exposed. You should return a copy.
}
}
This class has only final fields and only getter methods but is still mutable. Imagine this client code:
MyString myString = new MyString("test");
myString.getContent()[0] = 'f';
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
The use of final is to express your intention with java's language features and therefore enforce them by the compiler.
So making a variable final is good for primitive types, but you must take care if the variable is a reference. In this case you must either ensure that
the object you are referencing is also immutable or
only your instance has access to that object.
The later can only be ensured by the programmer. So take extra care when you return references.
Well, immutability is of course achieved in the way that an object is used, rather than by enforcement. You could always change a final field's value with Reflection.
The use of it is to allow the compiler to prevent you from breaking immutability, as well as to denote the need for immutability (such as when you use an inner class that uses a method-local reference).
'final' as the keyword's name suggest means that the attribute to which final keyword is attached can't be changed(in terms of value) in other words it behaves like a constant.if fields are not 'final' then inside local method you can change the value of fields.
I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance. (Unfortunately, the fields cannot be final because they needs to be populated by Hibernate.)
This worked well until I wanted to check another class throws the correct exception when called with an invalid instance of the model. The constructor of the model validates the arguments so reflection must be used to set the fields. This is extremely clumsy since the model have quite a few fields and the field names have to be hard-coded.
I can't mock the model either due to it being final. (Is it also debatable whether an interface should be used to enable mocking while keeping the class immutable. By having an interface, there's no way to programmatically mandate the methods must return the same value throughout the life of the instance.)
What do people usually do in this case? Is there any standard approach to this?
Generally speaking, you shouldn't want to mock data objects. Data objects should have no logic and no external dependencies, so there's not really much use to mocking the objects. Instead make it very easy to create fake instances that you can populate in methods as you'd like.
Furthermore, there are a few other reasons you might want to avoid treating a Hibernate-persisted object as immutable:
Hibernate-provided objects are inherently not thread-safe and therefore lose the thread-safety advantages that immutable value objects typically provide.
You may find your objects are actually proxies, possibly undercutting the final semantics.
Hibernate-controlled objects operate completely differently whether their session is still open (attached vs detached) making them a very poor choice for an immutable object. If your immutable object depends on session lifetime, it's not really immutable.
It sounds like some objects may be valid or invalid at the application layer, beyond database-layer validation. That makes it a little harder to encapsulate your validation concerns.
You are required to have a public no-arg constructor, which is antithetical to the kind of instance control typical of immutable value objects.
Because the objects are inherently mutable, it is more complicated to override equals and hashCode.
My advice? If you need more immutability and data validation guarantees than a Hibernate DAO can grant you, then create a real final immutable class with final fields (or a private constructor and static factory method), and then make a constructor (or static factory method) that copies in values from your Hibernate DAO.
If you decide this option, you are stuck with the overhead of having two data objects that change roughly in parallel, but you also get the benefit of separating concerns (in case the Hibernate object should diverge) and the ease of a truly-immutable, equals-and-hashcode-overriding, session-agnostic, guaranteed-valid object that you can easily create for tests.
For clarity, making a class final prevents it from being sub-classed. This is good in cases where the class doesn't need to be further refined.
Marking a class level variable as final means that it will only get assigned once. For primitives and immutable objects like String, this has the side effect of making the variable immutable (by default).
However, for mutable objects like Date, your variable will always reference the same instance, but others with access to that instance would still be able to change it's state. For example if you had a method
public Date getCreatedDate(){
return this.created; // class variable declared as private final Date created...;
}
Then any caller could access the created instance and change it's state. You would be better to only return truly immutable values, or return a clone.
public Date getCreatedDate(){
return this.created.clone();
}
EDIT
"I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance"
Your issue as I understand it is that Class A has a dependency on Class B. You wish to test class A and you are unable to mock class B, as you have marked it as final. You marked Class B as final to make it immutable (preventing it's internal state being changed). This is incorrect, as marking a class final prevents it from being sub-classed. It has nothing to do with the ability to change the internal state of an instance.
Your use of final does not have the desired effect. Marking the fields as final is not an option, and would not make the class immutable for the reasons stated above. The only way to protect your data is to prevent clients of your data from having access to the objects that make up it's internal state.
Assuming, that you won't be the only developer, you need to protect the users of your data from unintentional updates. Ensuring that you return clones from getters is one approach. Having team members sub-class and change data is just bad programming, not unintentional, and could be managed through policy and code review.
If you wish to protect your code from external interference by unknown developers (for example writing code that utilises the same namespace to inject their code), then other approaches are available such as package sealing.