[英]Creating an immutable object without final fields?
Can we create an immutable object without having all fields final? 我们可以创建一个不可变对象,而不是所有字段都是final吗?
If possible a couple of examples would be helpful. 如果可能的话,几个例子会有所帮助。
Declare all fields private and only define getters: 声明所有字段都是私有的,只定义getter:
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: 引用@Jon Skeet的评论,最终的类修饰符对以下内容很有用:
While an instance of just Private is immutable, an instance of a subclass may well be mutable.
虽然只是Private的实例是不可变的,但是子类的实例可能是可变的。 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.
所以接收类型为Private的引用的代码不能依赖它是不可变的而不检查它是否只是Private的实例。
So if you want to be sure the instance you are referring to is immutable you should use also final class modifier. 因此,如果您想确定您所指的实例是不可变的,那么您还应该使用最终的类修饰符。
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. x
字段,并使用反射对其进行变异。 (According to comments it can be done with final fields, but the results can be unpredictable.) The term "immutable", when used to descrbie Java objects, should mean thread-safe immutability. 当用于描述Java对象时,术语“不可变”应该意味着线程安全的不变性。 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.
它基于Java大人物如何使用这个术语。 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
字段; final
semantics was specifically upgraded to support immutable objects. final
语义被专门升级为支持不可变对象。 It is a very strong guarantee; 这是一个非常有力的保证; as a matter of fact,
final
fields is the only way; 事实上,
final
领域是唯一的方式; volatile
fields or even synchronized
block cannot prevent an object reference from being published before constructor is finished. volatile
甚至synchronized
块都无法阻止在构造函数完成之前发布对象引用。
是的,如果您创建的对象只包含私有成员并且没有提供setter,那么它将是不可变的。
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. 这个对象是不可变的。
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. 但是,没有必要在实际程序中执行此操作,如果您的类应该是不可变的,建议始终将字段设为final。
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???
当然,既然如此,你为什么不把它们标记为最终?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.