EugeneP
EugeneP

Reputation: 43

Can a class (an instance of the class), containing Random object variable be immutable?

The definition of immutability states that the state of an object (its data) cannot be altered after construction.

Here lays the question, in my opinion the state and the data the object contains are different things. Maybe the state means the data that is provided via getters?

It does not mean data marked private and not visible to the outside world, that can indeed change and not alter the state of an object.

Tell me if this is correct:

final class Obj1 {
 private final  int i; 
 private final  Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1(int i) {
   this.i = i;
  }  
 public getI() {
  j = rnd.nextInt(1000);
  return i;
 }
}

An instance of Obj1 is an immutable object.

final class Obj2 {
 private final int i; 
 private final Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1(int i) {
   this.i = i;
 }  
 public getI() {
   return i;
 }
 public getJ() {
   return j;
 }
}

Is an instance of Obj2 a mutable or immutable object and why? What if we get the next Random in the body of getJ each time the getter is invoked?

And what about such a class? Mutable/immutable and why?

final class Obj3 {
 private final  Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1() {
  }  
 public getJ() {
   return j;
 }
}

What about this one? Mutable/immutable and why?

final class Obj4 {
 private final Random rnd = new Random();
 public Obj1() {
  }  
 public getRnd() {
   return rnd.nextInt(1000);
 }
}

Upvotes: 4

Views: 516

Answers (3)

supercat
supercat

Reputation: 81179

It is perfectly legitimate for an immutable object to hold, and even expose, references to objects of arbitrary type if the references are recognized as identifying, rather than holding, the objects in question. For example, consider an object reference as being analogous to a VIN (Vehicle Identification Number--an alphanumeric string that uniquely identifies a vehicle, at least those manufactured in, or imported to, the U.S.), and imagine a repair shop might keeps a list of the VINs of the cars it has serviced. The cars themselves would hardly qualify as immutable objects, but the list wouldn't hold cars--it would identify cars. One could not look at a VIN and know what color a car was at the time it was serviced, but when a car enters the shop one could use the list of VINs to determine whether the car had visited before.

Upvotes: 0

Sergey Aslanov
Sergey Aslanov

Reputation: 2415

Good question. But this is question of terminology, while immutability is more about how you can use objects. Benefits of immutable objects:

  • You can pass them by reference and be sure no one change its state;
  • You don't need to think about synchronization;
  • More secure to use as keys in hash maps.

I would not state object as immutable if it changes it's state after construction, even if it has to setters.

Upvotes: 0

Joachim Sauer
Joachim Sauer

Reputation: 308061

An important point about immutability is that the obeservable state of the object must not change.

A very good example is java.lang.String, which is often quoted as the canonical example for an immutable class. It has a single non-final field, which is hash. hash holds the hash code, but defaults to 0. The hash code is calculated lazily the first time hashCode() is called and cached in that field. This way the internal state of a String object can change, but the observable state never changes (because hashCode() always returns the same value, no matter if it is calculated or just returning the cached value).

This means that the first three samples you provided (Obj1, Obj2, Obj3) are immutable: They have no setter and nothing else can change the value returned by their methods after the construction (it would be a good idea to declare the fields final, but it's not a requirement for immutability). Note also you can also leave out the Random field entirely in those classes, as it's not used after construction anyway.

I'd say the last sample (Obj4) is definitely mutable, because you change the state (i.e. what the next getRnd() call returns) each time you read from it (i.e. each time you call getRnd()).

So, to answer the question in the title: yes, a class referencing a Random object can be immutable, if the state of the Random object is not observable in the state of the class itself.

Upvotes: 7

Related Questions