Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immutablity in Java

I'm trying to put thing together in the definition of "immutability".

Item (3) here is saying, as one of the rules for creating immutable objects,

Dont allow subclasses to override methods. The simplest way to do this is to declare the class as final. ...

Overridden methods run on instances of subclasse(s). And, from what i know of, an immutable class is one of which the objects are "carved" in memory once they are instantiated-- none of its members and thus the object can't be changed.

Putting these together-- does the definition of "immutable" apply to classes as well as the objects? By finalizing the methods, I'm preventing its methods from being overridden whenever the class is extended. I don't see how finalizing the methods of an immutable class further add on making its objects immutable.

like image 648
Roam Avatar asked Nov 21 '13 22:11

Roam


4 Answers

If you're documenting your class as immutable, users of this class can safely assume that any instance of this class is immutable.

The problem is that if you allow your class to be subclassed, nothing forbids a subclass to add mutable state and methods, or even to override methods and make them mutate this new state. So the assumption made by the users of the class falls apart. Making the class final makes that impossible.

like image 157
JB Nizet Avatar answered Sep 21 '22 02:09

JB Nizet


I don't see how finalizing the methods of an immutable class further add on making its objects immutable.

If a class is final, making its methods final is redundant; since nothing can derive from the class, nothing can override the methods whether or not they are declared final. Provided the class you've defined is immutable, if it's final, there can't be any subclasses that aren't immutable (because there can't be any subclasses at all).

like image 25
T.J. Crowder Avatar answered Sep 20 '22 02:09

T.J. Crowder


I suppose that if the objects of a class are immutable, then you can say that the class is immutable too. String objects are immutable, so you could say that the String class is immutable.

When you make your methods final, you prevent some unknown subclass from doing the following:

@Override
public void yourMethod() {
    doSomeMutableThing();
}

It prevents a subclass from using inheritance and polymorphism to mutate (change) the data in your class. It also prevents a subclass from introducing some state of its own, which could be mutable.

Immutability isn't something you can just declare; you must enforce it using several techniques built-in to the Java language. Making your methods final is one of them.

like image 45
rgettman Avatar answered Sep 19 '22 02:09

rgettman


does the definition of "immutable" apply to classes as well as the objects?

Seeing as how a class is the blueprint of an object, yes?

The more important distinction to make here is that -- Adding final everywhere does NOT make your class / object immutable. at all.

Consider this:

final class Foobar {
  /*
   * in this context, final just means you can't rebind the variable.
   * it doesn't make the list immutable.
   */
  final List<String> notReallyImmutableList; 
  Foobar() {
    notReallyImmutableList = new ArrayList<String>();
  }

  final void addToList(String string) {
    notReallyImmutableList.add(string);  // totally legit if you have an instance of Foobar
  }
}
like image 41
yamafontes Avatar answered Sep 23 '22 02:09

yamafontes