1

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

6
  • Are you looking for a class that's like String functionality-wise? I didn't read your question that way at first, but if you do I'll change my answer with some String-specific examples. Commented Jun 19, 2009 at 9:47
  • String is a special citizen in Java. It isn't exactly a primitive type, but you also can't consider it a class. String is the only "class" that overloads the + operator. Adding two Strings will get new a new one. Operator overloading isn't allowed with regular classes. Commented Jun 19, 2009 at 9:52
  • Can't consider String a class??? Commented Jun 19, 2009 at 9:57
  • Does the String class override the + operator? Or does the compiler do the magic for you? Commented Jun 19, 2009 at 10:00
  • Yes, not functionality wise. Its behavior should be be same as what an immutable class should do and should not do. Commented Jun 19, 2009 at 10:01

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

6 Comments

There's an instance field in the Sun String implementation which is not final.
Nice point. 'final' is not a requirement. The hash var in String is the perfect example.
You should also think about making make the class final to ensure that no derived class exposes a protected field.
hashCode is not final because it is set lazily. It will have only one real value however so it will appear final.
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.
|
1

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.

3 Comments

Would really appreciate if you can explain this with the help of an example.
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!
Surely, will do it today itself. Thanks
1

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

1 Comment

And if he wants no subclasses, he should also make the class itself final.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.