I am looking for some efficient way for building a immutable class, just like Java's String class.
- 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.user8681– user86812009-06-19 09:47:08 +00:00Commented 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.kgiannakakis– kgiannakakis2009-06-19 09:52:10 +00:00Commented Jun 19, 2009 at 9:52
- Can't consider String a class???Tom Hawtin - tackline– Tom Hawtin - tackline2009-06-19 09:57:20 +00:00Commented Jun 19, 2009 at 9:57
- Does the String class override the + operator? Or does the compiler do the magic for you?Fortyrunner– Fortyrunner2009-06-19 10:00:01 +00:00Commented 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.Gaurav Saini– Gaurav Saini2009-06-19 10:01:51 +00:00Commented Jun 19, 2009 at 10:01
3 Answers
- All the fields must be
privateand preferablyfinal - Ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
- Fields must be populated from the Constructor/Factory
- Don't provide any setters for the fields
- Watch out for collections. Use
Collections.unmodifiable*. Also, collections should contain only immutable Objects - All the getters must provide immutable objects or use defensive copying
- 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.
6 Comments
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
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