• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to make class immutable ?

 
Ranch Hand
Posts: 153
Eclipse IDE Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear All,

I have one doubt and is that "How we can make Immutable class ?"

I mean we say that string is immutable class because it creates the new object and keep old one as it is .In the same way how can we make our own class as Immutable or how immutability can be achieved.

Will it be the case that our class be immutable after declaring it as final ?

Again one question is that "Are all wrapper classes are immutable ? "

Thank you all in advance.

Regards,
Chetan
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chetan Dorle wrote:Dear All,

I have one doubt and is that "How we can make Immutable class ?"



By not having any way to change its state after creation.

I mean we say that string is immutable class because it creates the new object and keep old one as it is .



No, we say that String is immutable because it doesn't provide any means to change its state after creations. The fact that we have to create a new String object if we want a String with a different state is a +result+ of String's immutability.

Will it be the case that our class be immutable after declaring it as final ?



No. Your class being final simply means that nothing can extend it. It has nothing to do with whether an instance of that class can change its state after creation. There is no keyword or language level construct to indicate immutability (though I wish there was).

Again one question is that "Are all wrapper classes are immutable ? "



You can discover this for yourself by look at all their javadocs. If they say that the class is immutable, or if the class doesn't provide any means to change its state, then it's immutable.
 
Saloon Keeper
Posts: 15510
363
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To make a class final, you need to make sure it's internal state can not change, or at least not in such a way that will be visible to the outside world.

This means your class can only have pure functions. None of the methods may change important fields. If the constructor accepts a mutable class as an argument, you should make a defensive copy of the argument before assigning it to a field. When you want to return a mutable field, you should instead make a copy of the object and return that copy.

All your methods should be final to prevent a subclass from turning them into versions that break these properties. The easiest way to do this is to just make the class itself final.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:To make a class final, you need to make sure it's internal state can not change,



Presumably you meant, "To make a class immutable..."
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Errr.... yes ^^'
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
An immutable object is an object whose state cannot be modified after it is created.

Following is the template for creating immutable objects:

1) Make all fields private
2) Don't provide mutators
3) Ensure that methods can't be overridden by either making the class final (Strong Immutability) or making your methods final (Weak Immutability)
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are forgetting a very important step. You need to perform defensive copying in the constructor and any accessors, if they respectively accept and return mutable types.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chetan Dorle wrote:Will it be the case that our class be immutable after declaring it as final ?


No, but it's an important part of it. While it is possible to create a non-final immutable class, it is not possible to create an immutable class that is publically extendable (or perhaps nonsensical is a better term), because then anyone could add a mutable portion to it. So the easiest thing generally is to make it final. However, as others have said, that's not the end of it...

Winston
 
AbdulRab Khan
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:You are forgetting a very important step. You need to perform defensive copying in the constructor and any accessors, if they respectively accept and return mutable types.



Thanks Stephan van Hulst, I was'nt aware of this step
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To illustrate this problem:

In the first snippet, the class is not really immutable, because you can change its state by changing the Mutable object you pass to the constructor, or by changing it after you retrieve it with the accessor method.
The second snippet demonstrates an Immutable variant. It uses a copy constructor in the Mutable class to make defensive copies of it before it stores or returns the object.
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can also solve the problem for accessor methods by returning read-only views of the mutable object in question. For example, if you have a class which contains a list of objects, and you want to return the list from a method, you can return a read-only view of it by returning Collections.unmodifiableList(myList);
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, even that won't make the class immutable unless the elements of the List are immutable too. If not, you can modify individual elements of the unmodifiable List; unmodifiable only means the List cannot have elements added, removed or replaced, it doesn't say anything about the content of the elements themselves.
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Err yes. My bad.
 
Karn Kumar
Ranch Hand
Posts: 153
Eclipse IDE Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you all , Guys ....for the examples and your replies.

here is one link i found http://download.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
 
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Key Notes:-

Declare class as final (strong immutability)
No parameterized constructor (only default is allowed)
Only allow get() methods are allowed
Member variables of class as private and final.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Santosh Kumar Nayak wrote:No parameterized constructor (only default is allowed)


How are you going to give your objects any state? Immutable classes usually have constructors that do have parameters. You just have to make sure that the arguments to the constructor are either immutable as well, or are copied defensively.
 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chetan Dorle wrote:
There is no keyword or language level construct to indicate immutability (though I wish there was).



Well you can always use C++ which has the const keyword.

Still the keyword approach has its limits and that's because immutability comes in two flavours, formal and by design, and that's really an issue. To resolve it C++ has had to introduce a counter measure to const called mutable.

So with the C++ example in mind and further discouraged by the general threat that "if you suggest a language change you must donate a kidney" I think Java should stay as it is.

 
Santosh Kumar Nayak
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can Immutable class have a reference to a mutable class ?
 
Marshal
Posts: 79180
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, but you have to take defensive copies of any mutable fields if they enter or leave the class.
 
Santosh Kumar Nayak
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are two classes : Person and Employee.

Now object of Person class has been passed to Employee class as argument.

Now my question is how should we make sure that Object of Person class remains unaltered (class Person is mutuable).

There are chances that within class Employee the object of Person class can be altered.


 
Campbell Ritchie
Marshal
Posts: 79180
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Person object cannot ensure constancy of its state in those circumstances.
The Employee object must take a defensive copy of the Person object or its fields to establish immutability. That will usually be done in such a manner as not to alter the state of the Person object.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Santosh Kumar Nayak wrote:There are chances that within class Employee the object of Person class can be altered.


In which case, I wonder on what basis you could consider an Employee to be "immutable"?

As previously explained, whatever way you choose to do it, it is going to cause an Employee to hold a snapshot of a Person; and in that case, I'd say that the two classes are unrelated, simply because of their differing requirements for mutability.

Winston
 
Santosh Kumar Nayak
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you elaborate as what do you mean by defensive copy of the object.
 
Campbell Ritchie
Marshal
Posts: 79180
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You create another object with the same details in its fields.. It may be mutable, but you keep it hidden as a private field and its state never changes. If any of those fields are mutable, they would need to be copied too.
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
from the discussion here, i have a following code. let me know whether it is correct or not.

import java.util.ArrayList;
import java.util.Date;

class Address{

String state;
String city;
String pin;

public String getState() {
   return state;
}
public void setState(String state) {
   this.state = state;
}
public String getCity() {
   return city;
}
public void setCity(String city) {
   this.city = city;
}
public String getPin() {
   return pin;
}
public void setPin(String pin) {
   this.pin = pin;
}

public Address(){}
public Address(String state, String city, String pin) {
   super();
   this.state = state;
   this.city = city;
   this.pin = pin;
}

}

final class Person {
private final Integer immutableField1;
private final String immutableField2;
private final Date mutableField;
final private ArrayList<String> list;
private final Address adrs;

public Integer getImmutableField1() {
   return immutableField1;
}
public String getImmutableField2() {
   return immutableField2;
}
public Date getMutableField() {
   return new Date();
}
public ArrayList<String> getList() {
   return  (ArrayList<String>) list.clone();
}
public Address getAdrs() {
   Address temp_adrs=new Address();
   temp_adrs.setState(adrs.getState());
   temp_adrs.setCity(adrs.getCity());
   temp_adrs.setPin(adrs.getPin());
   return temp_adrs;

}
public Person(Integer immutableField1, String immutableField2,
       Date mutableField, ArrayList<String> list, Address adrs) {
   super();
   this.immutableField1 = immutableField1;
   this.immutableField2 = immutableField2;
   this.mutableField = (Date) mutableField.clone();
   this.list = (ArrayList<String>) list.clone();
   Address temp_adrs=new Address();
   temp_adrs.setState(adrs.getState());
   temp_adrs.setCity(adrs.getCity());
   temp_adrs.setPin(adrs.getPin());
   this.adrs = temp_adrs;
}

}

class immutable_demo{
public static void main(String[] args)    {
   Date d=new Date();
   ArrayList<String> list=new ArrayList<String>();
   list.add("amit");

   Address adrs=new Address("mh","pune","411030");

   Person im = new Person(100,"test", d,list,adrs);
   System.out.println("model="+im.getAdrs().getPin());
   System.out.println("adrs="+adrs.getPin());
   adrs.setPin("411009");
   System.out.println("model="+im.getAdrs().getPin());
   System.out.println("adrs="+adrs.getPin());
}

}
 
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Amit Ghone wrote:i have a following code. let me know whether it is correct or not


Define 'correct'?

If you're talking about immutability then you have not achieved it. You Address class has setter methods which allow you to mutate the object post creation. Your Person class takes a Date object in its Constructor but then returns a different Date object through it's accessor method. As a matter of style and maintainability, the names you give your fields and variables is very important. Names such as 'immutableField2' are very poor and make it very difficult to read your code. I strongly recommend you refactor your code to use meaningful names.

Perhaps if you told us what you are trying to achieve it would make it easier for folks to help you.

Lastly, it's encouraged that you Use Code Tags when posting code to the forum to make it as easy as possible to read. I've copied your code below for reference.



 
Amit Ghone
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Tim,

i have a class Person. i want to make class Person and its object immutable
i have Address class which is a mutable class.
Person class contains reference to Address class and 1 ArrayList.
i'm confused with concept of immutability of user defined class.
let me know any changes are need to be done
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To make a class immutable you can turn all attributes into  private, do not create any setter method, and then just use the constructor or a Builder to set the attributes.
Here a simple example:

 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to CodeRanch!

Alexandre Queiroz de Oliveira wrote:To make a class immutable you can turn all attributes into  private, do not create any setter method, and then just use the constructor or a Builder to set the attributes.


This is not complete. You need to make sure that the fields are immutable as well, or that you perform defensive copies in the constructors and getters.
 
Alexandre Queiroz de Oliveira
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Welcome to CodeRanch!

Alexandre Queiroz de Oliveira wrote:To make a class immutable you can turn all attributes into  private, do not create any setter method, and then just use the constructor or a Builder to set the attributes.


This is not complete. You need to make sure that the fields are immutable as well, or that you perform defensive copies in the constructors and getters.



So, do you think that turning the attributes into final this will become complete?
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, not if those types are mutable. Refer to my example on 13 November 2011 in this thread. The class NotReallyImmutable has a private final field, and does not have any setters. It's still not immutable, as the main method demonstrates.
 
Roses are red, violets are blue. Some poems rhyme and some don't. And some poems are a tiny ad.
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic