Examples of immutable classes

I already know the definition of immutable classes but I need a few examples.


Solution 1:

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 - a 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 except DateTimeException are immutable. Most of the classes of the subpackages of java.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

Solution 2:

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.

Solution 3:

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.