Reputation: 43
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
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
Reputation: 2415
Good question. But this is question of terminology, while immutability is more about how you can use objects. Benefits of immutable objects:
I would not state object as immutable if it changes it's state after construction, even if it has to setters.
Upvotes: 0
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