tags:

views:

351

answers:

5

I am looking for some efficient way for building a immutable class, just like Java's String class.

+1  A: 

An object is immutable if none of its fields can be modified, so those fields must be final. If you don't want your object to be subclassed, you can make the class itself final as well, just like String is. To easily construct an immutable object with a lot of information, you should look at the Factory Pattern

For more information, see Wikipedia

Jorn
And if he wants no subclasses, he should also make the class itself final.
André
good point, I'll add it.
Jorn
+1  A: 

If you populate all fields using the constructor and make the fields final - you are partway there.

If the fields use custom types - you may need to make them immutable as well.

Any fields that are collections should use the unmodifiable collections - to be on the safe side.

You need to worry about the object graph!

Any methods on the object need to take care with non-final fields. E.g. String.add creates a new String. If you need to mutate one field - do so via a copy constructor.

Finally make the object final.

Fortyrunner
Would really appreciate if you can explain this with the help of an example.
Gaurav Saini
If you haven't already got a copy - get a copy of Effective Java by Josh Bloch. He explains this far better than I ever can!
Fortyrunner
Surely, will do it today itself. Thanks
Gaurav Saini
+8  A: 
  1. All the fields must be private and preferably final
  2. Ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
  3. Fields must be populated from the Constructor/Factory
  4. Don't provide any setters for the fields
  5. Watch out for collections. Use Collections.unmodifiable*. Also, collections should contain only immutable Objects
  6. All the getters must provide immutable objects or use defensive copying
  7. Don't provide any methods that change the internal state of the Object.

Tom Hawtin pointed out that final can be optional. String class has a cache hash var that is only assigned when the hash function is called.

bruno conde
There's an instance field in the Sun String implementation which is not final.
Tom Hawtin - tackline
Nice point. 'final' is not a requirement. The hash var in String is the perfect example.
bruno conde
You should also think about making make the class final to ensure that no derived class exposes a protected field.
DR
@DR, I agree. Immutable classes should be final.
bruno conde
hashCode is not final because it is set lazily. It will have only one real value however so it will appear final.
Peter Lawrey
I use immutable classes which extend other immutable classes all the time. Not sure why you need to make an immutable class final unless you are concerned that it might be extended with a mutable one. Otherwise I agree.
Peter Lawrey
+1  A: 

Joshua Bloch tells you how to do it. Have a look at his "Effective Java".

duffymo
+1  A: 

Here is a link to an article on javaranch best article ever read for immutable objects

Rahul Garg