How to define an immutable object in a mutable Java class? - java

In a class, I want to define an empty object and use it anywhere we need it. This object needs to be immutable to avoid accidentally modification. If this object is defined as a public static final member of the class, the object could be changed if the class itself is mutable.
What's the good way to create an immutable object in a mutable class?

If you need to make a class immutable then you need to fulfill this requirements:
all its fields final
the class declared as final
the this reference is not allowed to escape during construction
Any fields which refer to mutable data objects are:
private
have no setter method
they are never directly returned of otherwise exposed to a caller
if they are changed internally in the class this change is not visible and has no effect outside of the class

If you cannot modify the class to make it immutable (final class with final fields, etc.) than just write yourself an immutable wrapper (proxy from GOF?) and use it instead. Inside it can has a delegate to your original class instance.

Related

How is immutability actually implemented in String class and mutability in StringBuffer and StringBuilder in code?

I know the prerequisites for a class to be made immutable. I looked into the code, there were no setters for any variable defined in String. For StringBuffer and StringBuilder, there were two setters:
setLength which called the same named setters of parent AbstractStringBuilder.
setCharAt which manipulated the char value[] of parent AbstractStringBuilder.
String is "immutable" because its API (the public methods it defines) provides no way for a caller to change its state. Other classes, like StringBuilder, are mutable because they do provide "mutators", or methods that change the state of the class.
Under the covers there's nothing different between mutable or immutable objects. An object is just the primitive and reference values that make up its fields, and all fields are conceptually mutable (ignoring the final keyword for the moment). But by restricting the visibility of these fields (e.g. making them private) and defining methods that limit what a caller can do (like defining a getter but not a setter) you can provide a guarantee that instances of the class will be immutable, which is to say you promise none of its fields (or the objects they reference) will change over its lifetime.
By using the final keyword you can be even more explicit that a class is immutable. If you simply don't provide mutator methods, it's still possible for a class to be mutable if some private method mutates the class. If all the fields in a class are marked final, that's not (normally) possible. You can be confident any class with only final primitive (or immutable) fields is immutable*. That isn't the only way to guarantee immutability, but it is the clearest - any attempt to mutate the class would be a compiler error.
* The class itself also has to be declared final, otherwise someone could potentially create a mutable subclass. But again, there are other ways to ensure immutability. Using final everywhere is just the easiest to see.
There are a lot of things here.
All fields are private.
There are no setters / mutators.
Construction injection of arguments (using which String has to be constructed).
Reference to underlying char array (char[] value) does not leak out of this class.
Mutability is not merely defined by the presence or absence of setter/mutator methods.
In the case of StringBuilder and StringBuffer, there's a plethora of other methods (e.g. all the append() methods) that alter the internal state of the object, and hence make it mutable.

In immutable class why fields are marked as private?

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.

non final - immutable classes

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

Cloning and serializing a final object

When a class is declared as final, is it possible to clone or serialize it's objects? Or is this impossible because final prevents the extending of subclasses, therefore preventing cloning and serialization from implemented?
Final for classes --> You can't extend the class.
Final for objects --> You can't change the reference to the object.
Serializable/cloning--- > These concepts are for objects. You implement an interface to make the object of a perticular class Serializable/Cloneable.
So, yes, when a class is declared as Final, it is possible to Serialize/clone its objects provided you implement the necessary interfaces.
I think you may be not clear on some OOP concepts and their Java implementation.
You extend classes, while you serialize and clone objects.
There is a Singleton pattern that allows only a single object to be created, but that is a whole other story.

"hide" mutable objects with a factory method

I read some lines in Effective Java: Programming Language Guide
Joshua Bloch and find out that I should avoid the usage of mutable objects. Because of I read the book I know how to make a mutable object immutable (e.g. usage of private and final modifier).
Well however I have a "dummy" data holder class with some private fields. Each field is accessable with a get method and also a corresponding set method. So because of this set methods objects of this class are not immutable.
The question is now how to avoid these set methods? Pass all (e.g. 20) parameters to the object constructor? I think this is not really good design because I have to keep care of the order of parameters, have to pass null references if I do not want to set a special parameter and so on.
So I think about following approach:
Create an interface with all get methods and let it implement from dummy data holder class
Create an abstract class with a private constructor and a static factory method which returns the "get" interface instance of the data holder object.
In the static factory method I configure the data holder object with all necessary set methods
Make the data holder class package private so that a object can only be instanciated over the static factory method which is defined in the abstract class
In the next step I store the configured and created data holder objects in a list.
What is the best approach to read out a object an modify the object although it is immutable? Create a new object with a static factory method which sets the new value internally and replace it with the object in the list?
As #NilsH pointed out: you should go for the Builder pattern, ideally based on a fluent interface.
As an example, you may look at make-it-easy.

Categories