I already know the definition of immutable classes but I need a few examples.
-
String is a good example. Are there any other immutable classes? – user635041 Feb 26 '11 at 00:08
-
@user: Usually the javadoc for a particular class will state if it is immutable or not. – Jeremy Feb 26 '11 at 00:09
-
1is Class AccessControlContext a immutable class – user635041 Feb 26 '11 at 00:23
-
All answers below (expect one or two) explains how to create Immutable class or says what is immutable rather than answering the actual question asked. – Jayesh Feb 27 '16 at 07:01
10 Answers
Some famous immutable classes in the Standard API:
java.lang.String (already mentioned)
The wrapper classes for the primitive types: java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float
java.lang.StackTraceElement (used in building exception stacktraces)
Most enum classes are immutable, but this in fact depends on the concrete case. (Don't implement mutable enums, this will screw you up somewhen.) I think that at least all enum classes in the standard API are in fact immutable.
java.math.BigInteger and java.math.BigDecimal (at least objects of those classes themselves, subclasses could introduce mutability, though this is not a good idea)
java.io.File. Note that this represents an object external to the VM (a file on the local system), which may or may not exist, and has some methods modifying and querying the state of this external object. But the File object itself stays immutable. (All other classes in java.io are mutable.)
java.awt.Font - representing a font for drawing text on the screen (there may be some mutable subclasses, but this would certainly not be useful)
java.awt.BasicStroke - a helper object for drawing lines on graphic contexts
java.awt.Color - (at least objects of this class, some subclasses may be mutable or depending on some external factors (like system colors)), and most other implementations of java.awt.Paint like
- java.awt.GradientPaint,
- java.awt.LinearGradientPaint
- java.awt.RadialGradientPaint,
- (I'm not sure about java.awt.TexturePaint)
java.awt.Cursor - representing the bitmap for the mouse cursor (here too, some subclasses may be mutable or depending on outer factors)
java.util.Locale - representing a specific geographical, political, or cultural region.
java.util.UUID - an as much as possible globally unique identifier
while most collections are mutable, there are some wrapper methods in the java.util.Collections class, which return an unmodifiable view on a collection. If you pass them a collection not known anywhere, these are in fact immutable collections. Additionally,
Collections.singletonMap()
,.singletonList
,.singleton
return immutable one-element collections, and there are also immutable empty ones.java.net.URL and java.net.URI - representing a resource (on the internet or somewhere else)
java.net.Inet4Address and java.net.Inet6Address, java.net.InetSocketAddress
most subclasses of java.security.Permission (representing permissions needed for some action or given to some code), but not java.security.PermissionCollection and subclasses.
All classes of
java.time
exceptDateTimeException
are immutable. Most of the classes of the subpackages ofjava.time
are immutable too.
One could say the primitive types are immutable, too - you can't change the value of 42, can you?
is Class AccessControlContext a immutable class
AccessControlContext does not have any mutating methods. And its state consists of a list of ProtectionDomains (which is an immutable class) and a DomainCombiner. DomainCombiner is an interface, so in principle the implementation could do something different on each call.
In fact, also the behaviour of the ProtectionDomain could depend on the current policy in force - it is disputable whether to call such an object immutable.
and AccessController?
There are no objects of type AccessController, since this is a final class with no accessible constructor. All methods are static. One could say AccessController is neither mutable nor immutable, or both.
The same is valid for all other classes which can't have objects (instances), most famously:
- java.lang.Void
- java.lang.System (but this has some mutable static state -
in
,out
,err
) - java.lang.Math (this too - the random number generator)
- java.lang.reflect.Array
- java.util.Collections
- java.util.Arrays

- 73,284
- 20
- 146
- 210
-
java.lang.Class is quite modifiable. For instance `getPackage(){Package.getPackage(this);}` can return null and then a real package since it relies on the classLoader impl. Also internally it uses a *a lot* of caching and state. – bestsss Feb 26 '11 at 00:43
-
ŭlo, I don't know about java.awt.Font either, it has protected fields and some subclasses might be modifiable but java.awt.Font, itself, is generally considered unmodifiable. java.awt.BasicStroke is unmodifiable, if you want to add to the list :) – bestsss Feb 26 '11 at 00:53
-
3"you can't change the value of 42, can you?"... you can't mainly because it is THE Answer :) – Andrea Ligios Oct 31 '12 at 13:38
-
1It's interesting to note that BigDecimal is technically not immutable, since it's not final. – KNU Feb 25 '15 at 19:48
-
1According to "Java Concurrent In Practice", java.net.URL is not immutable as many of its fields are not final. So if there is no "happens-before" relationship between multiple threads, users of it may see a partially initialized object. – Adrian Liu Feb 06 '17 at 03:30
-
Immutable classes cannot be changed after construction. So, for example, a Java String
is immutable.
To make a class immutable, you have to make it final
and all the fields private
and final
. For example the following class is immutable:
public final class Person {
private final String name;
private final int age;
private final Collection<String> friends;
public Person(String name, int age, Collection<String> friends) {
this.name = name;
this.age = age;
this.friends = new ArrayList(friends);
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public Collection<String> getFriends() {
return Collections.unmodifiableCollection(this.friends);
}
}
I have added in a method in the code example showing how to handle collections, an important point.
Where possible you should make classes immutable, because then you don't have to worry about things like thread safety.

- 2,406
- 4
- 28
- 41

- 4,181
- 7
- 42
- 66
-
9You still can change the `friends` `Collection` after `Person` construction if you keep the reference. It should clone `friends`. And with three parameters you should start to think in using a [builder](http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2) =) – superfav Feb 26 '11 at 00:53
-
Yes, `Person` as coded is mutable since it keeps a reference to the friends Collection passed in the constructor. – Steve Kuo May 29 '11 at 21:43
-
-
Above code throws null pointer exception, it should be - this.friends = new ArrayList(friends); – anmolmore Jun 13 '15 at 17:08
-
@superfav did the poster change the answer per your comment yet ? Normally they would ack the change in an Update comment. Seems like he did change it per anmolmore's comment but did not bother to ack. – killjoy Nov 17 '18 at 14:42
-
@killjoy Yes, it was _fixed_ by Community and that introduced the bug anmolmore commented. See https://stackoverflow.com/revisions/5124054/2 and the following fixes. – superfav Nov 17 '18 at 19:04
-
Is there a possibility to create a default behaviour from the list whenever this class is called? – JSG Feb 13 '23 at 07:59
It's important to keep in mind that declaring a class as final does not means that it is "immutable", this basically means that this class cannot be extended (or specialized).
Immutable classes must have private and final fields (without setters), so after its construction, it cannot have its field values changed.

- 3,492
- 2
- 16
- 8
-
All fields are already private still why it is further to use final. – Ajay Takur Oct 14 '18 at 16:07
-
-
@AjayTakur so that you can not change the value of variables which is what we want in immutability – mss Jan 04 '20 at 10:26
To create a class immutable, you need to follow following steps:
- Declare the class as final so it can’t be extended.
- Make all fields private so that direct access is not allowed.
- Don’t provide setter methods for variables
- Make all mutable fields final so that it’s value can be assigned only once.
- Initialize all the fields via a constructor performing deep copy.
- Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.
An example can be found here.
We can also use Builder Pattern to easily create immutable classes, an example can be found here.

- 5,132
- 3
- 28
- 37
-
That link has way too much noise, overly complicated and is unreadable with the contrast. This I found to be simpler: https://codereview.stackexchange.com/questions/127391/simple-builder-pattern-implementation-for-building-immutable-objects – killjoy Nov 17 '18 at 14:49
LocalDate, LocalTime and LocalDateTime classes (since 1.8) are also immutable. In fact, this very subject is on the OCAJSE8 (1Z0-808) exam, and that's precisely why I decided to treat it as not a mere comment.
All primitive wrapper classes (such as Boolean, Character, Byte, Short, Integer, Long, Float, and Double) are immutable.
Money and Currency API (slated for Java9) should be immutable, too.
Incidentally, the array-backed Lists (created by Arrays.asList(myArray)
) are structurally-immutable.
Also, there are some border-line cases such as java.util.Optional (featured on the OCP exam, 1Z0-809), which is immutable if the contained element is itself immutable.

- 671
- 10
- 19
String
is a good "real world" example of an immutable class. And you can contrast it with the mutable StringBuilder
class.
Most of the Java classes used for reflection are immutable. And some of the others are "almost immutable": e.g. the classes that implement Accessible
have just a setAccessible
method that changes the state of the Accessible
instance.
I'm sure there are lots more in the standard class libraries.

- 698,415
- 94
- 811
- 1,216
-
1@user635014 All the primitive wrappers (Integer, Long, etc) are immutable. Also ReadOnlyCollection (although objects contained can still be mutated). Most classes in Java are (sadly, partially due to language constructs) mutable. – Feb 26 '11 at 00:25
The Sun (Oracle) documentation has an excellent checklist on how to make an immutable object.
- Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
- Make all fields final and private.
- Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
- If the instance fields include references to mutable objects, don't allow those objects to be changed:
- Don't provide methods that modify the mutable objects.
- Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
From: http://download.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
The site also provides examples of its use in a concurrency context but immutability is also useful when writing libraries. It assures that callers to the library are able to only change what we allow them to.

- 16,149
- 12
- 63
- 66
Immutable class is a class which once created, it’s contents can not be changed. Immutable objects are the objects whose state can not be changed once constructed. Example- String & all java wrapper classes.
Mutable objects are the objects whose state can be changed once constructed.example- StringBuffer Once value changed memory location altered. See below example -
public static void immutableOperation(){
String str=new String("String is immutable class in Java object value cann't alter once created...");
System.out.println(str);
str.replaceAll("String", "StringBuffer");
System.out.println(str);
str.concat("Concating value ");
System.out.println(str + "HashCode Value " + str.hashCode());
str=str.concat("Concating value ");
System.out.println(str + "HashCode Val " + str.hashCode());
}
public static void mutableOperation(){
StringBuffer str=new StringBuffer("StringBuffer is mutable class in Java object value can alter once created...");
System.out.println(str + "HashCode Val - " + str.hashCode());
str.replace(0, 12, "String");
System.out.println(str + "HashCode Val - " + str.hashCode());
}

- 41
- 2
I like to use examples that have a mutable property. This helps understand how immutable classes truly function.
Mutable class
class MutableBook {
private String title;
public String getTitle(){
return this.title;
}
public void setTitle(String title){
this.title = title;
}
}
And an immutable implementation using the mutable instance of a book.
public class ImmutableReader {
private final MutableBook readersBook;
private final int page;
public ImmutableReader(MutableBook book) {
this(book, 0);
}
private ImmutableReader(MutableBook book, int page){
this.page = page;
// Make copy to ensure this books state won't change.
MutableBook bookCopy = new MutableBook();
bookCopy.setTitle(book.getTitle());
this.readersBook = bookCopy;
}
public MutableBook getBook() {
// Do not return the book, but a new copy. Do not want the readers
// book to change it's state if developer changes book after this call.
MutableBook bookCopy = new MutableBook();
bookCopy.setTitle(this.readersBook.getTitle());
return bookCopy;
}
public int getPage() {
// primitives are already immutable.
return page;
}
/**
* Must return reader instance since it's state has changed.
**/
public ImmutableReader turnPage() {
return new ImmutableReader(this.readersBook, page + 1);
}
}
In order for your class to be truly immutable, it must meet the following cirteria:
- All class members are declared final.
- All variables used in a class at the class level must be instantiated when the class is constructed.
- No class variable can have a setter method.
- This is implied from the first statement, but want to make it clear that you cannot change the state of the class.
- All child object must be immutable as well, or their state never changed in the immutable class.
- If you have a class with mutable properties, you must lock it down. Declare it private, and ensure you never change it's state.
To learn a little more take a look at my blog post: http://keaplogik.blogspot.com/2015/07/java-immutable-classes-simplified.html

- 2,369
- 2
- 25
- 26
While creating an object of an immutable class one must ensure that external reference will not be stored. However, the values does matter here. In the example given below, I have a class called Fruits inside there is a List. I have made the class immutable by making the List private and final as well as there is no setter provided.
If I am instantiating an object of Fruit, the constructor will be given a list.Client program does have a reference of this List already(client side) and hence the List can be modified easily and hence the immutability of the class will be lost.
To address this problem , I am creating a new List in the constructor which copies all the values supplied by the client.
Now if the client adds more values in the list, the external reference will get affected however, I am not storing that external reference anymore in my immutable class.
This can be verified by overriding an hashcode() in the immutable class. No matter how many times the client modifies the list the hashcode of my immutable class object will remain unchanged, as the list it accepts is no more pointing to the external list.
public class Fruit {
private final List<String> fruitnames;
public Fruit(List<String> fruitnames) {
this.fruitnames = new ArrayList<>(fruitnames);
}
public List<String> getFruitnames() {
return new ArrayList<>(fruitnames);
}
@Override
public int hashCode() {
return getFruitnames() != null ? getFruitnames().hashCode(): 0;
}
}
//Client program
public class ImmutableDemo {
public static void main(String args[]){
List<String> fruitList = new ArrayList<>();
fruitList.add("Apple");
fruitList.add("Banana");
//Immutable Object 1
Fruit fruit1 = new Fruit(fruitList);
//fruitHash is-689428840
int fruitHash = fruit1.hashCode();
System.out.println("fruitHash is" +fruitHash);
//This value will not be added anymore as the state has already been defined and
//now it cant change the state.
fruitList.add("straberry");
//fruitHash1 is-689428840
int fruitHash1 = fruit1.hashCode();
System.out.println("fruitHash1 is" +fruitHash1);
}
}

- 51
- 2