2014-08-30 18 views
3

对于创建不可变类我有疑问。强制使字段作为final来使类不可变

根据java文档。

  1. 我做出了最终的类(没有人可以延长)
  2. 场是私有的。
  3. 无设置功能。
  4. 如果字段是可变的,则发送字段的克隆拷贝。

我的疑问是,强制要求我的班级成绩为final

+0

当然。否则,有人可能会以可变的方式扩展它。 – 2014-08-30 16:22:36

+0

@OliCharlesworth,这个类是最终的,所以它不能被子类化。 – Paul 2014-08-30 16:24:18

+0

@保罗:啊,对不起,我误解了这个问题(以为这是关于*班*的最终决定)。 – 2014-08-30 16:24:46

回答

3

如果没有setter方法(并且大概没有其他方法影响字段的值)并且字段本身是private,则将它们标记为final有点多余。尽管如此 - 这是许多项目标准遵循的良好的防御性做法。

+1

私有字段不能被继承类访问(这是'private'和'protected'之间的区别)。此外,OP已经提到这个阶级本身是最终的,所以它不能延伸。 – Mureinik 2014-08-30 16:24:34

+0

@YS Bhai提到这一点,同样的问题已经回答[这里](http://stackoverflow.com/questions/16061030/must-all-properties-of-an-immutable-object-be-final) – 2014-08-30 16:24:55

+0

@SotiriosDelimanolis好因为基类没有setter方法。 – Paul 2014-08-30 16:25:32

0

不可变=不可更改。所以最终确定属性是个好主意。如果一个对象的所有属性都不能被保护,我不会说这个对象是不可变的。

但是如果一个对象没有为它的私有属性提供任何setter对象,它也是不可变的。

immutable对象永远不会改变,但它所指的任何东西都可能会改变。 Deep immutability更强大:基础对象和任何可以从中导航的对象都不会改变。

+0

如果我们谈论*行为*不变性,那么只要内部状态从来没有可观察到的效果,就很可能会改变内部状态。典型的例子是某种引用计数机制。 – 2014-08-30 16:33:25

2

虽然为很多人说其不是强制性标记字段作为最终我会ATLEAST说在一种情况下,我能想到的,你需要标记字段,最后,这是在的情况下,如果你想使你的不变类线程安全。

根据Java的内存模型: -

的对象被认为是完全初始化时,它的构造完成。在该对象完全初始化后,只能看到对象的引用的线程保证能够看到该对象最终字段的正确初始化值。

JLS final thread safety

所以,如果你有你在构造函数非最终变量初始化实例变量的不可变类则没有线程安全保障作为写入到非最终变量可能不可见即使在构造完全运行其他线程(注重建,这是非常困难的,因为这可能会在高并发应用程序发生)

相关问题