Reputation: 10588
Can we create an immutable object without having all fields final?
If possible a couple of examples would be helpful.
Upvotes: 9
Views: 2728
Reputation: 39164
Declare all fields private and only define getters:
public final class Private{
private int a;
private int b;
public int getA(){return this.a;}
public int getB(){return this.b;}
}
citing @Jon Skeet's comment, final class modifier is useful for:
While an instance of just Private is immutable, an instance of a subclass may well be mutable. So code receiving a reference of type Private can't rely on it being immutable without checking that it's an instance of just Private.
So if you want to be sure the instance you are referring to is immutable you should use also final class modifier.
Upvotes: 7
Reputation: 45433
The term "immutable", when used to descrbie Java objects, should mean thread-safe immutability. If an object is immutable, it is generally understood that any thread must observe the same state.
Single thread immutability is not really interesting. If that is what really referred to, it should be fully qualified with "single thread"; a better term would be "unmodifiable".
The problem is to give an official reference to this strict usage of the term 'immutable'. I can't; it is based on how Java bigshots use the term. Whenever they say "immutable object", they are always talking about thread safe immutable objects.
The idiomatic way to implement immutable objects is to use final
fields; final
semantics was specifically upgraded to support immutable objects. It is a very strong guarantee; as a matter of fact, final
fields is the only way; volatile
fields or even synchronized
block cannot prevent an object reference from being published before constructor is finished.
Upvotes: 3
Reputation: 1499870
Yes, it is - just make sure that your state is private, and nothing in your class mutates it:
public final class Foo
{
private int x;
public Foo(int x)
{
this.x = x;
}
public int getX()
{
return x;
}
}
There's no way of mutating the state within this class, and because it's final you know that no subclasses will add mutable state.
However:
x
field accessible in the above code, and mutate it with reflection. (According to comments it can be done with final fields, but the results can be unpredictable.)Upvotes: 6
Reputation: 12175
I believe the answer is yes.
consider the following object:
public class point{
private int x;
private int y;
public point(int x, int y)
{
this.x =x;
this.y =y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
This object is immutable.
Upvotes: 1
Reputation: 206786
A class is immutable if it does not provide any methods that are accessible from the outside that modify the state of the object. So yes, you can create a class that is immutable without making the fields final. Example:
public final class Example {
private int value;
public Example(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
However, there is no need to do this in real programs, and it is recommended to always make fields final if your class should be immutable.
Upvotes: 1
Reputation: 32949
Yes. Make the fields private. Don't change them in any methods other than the constructor. Of course, that being the case, why wouldn't you label them as final???
Upvotes: 0
Reputation: 1328
Yes, if you created an object that contained only private members and provided no setters it would be immutable.
Upvotes: 1