【问题标题】:Final fields and Immutable Classes最终字段和不可变类
【发布时间】:2015-08-01 03:01:01
【问题描述】:

据此:A Strategy for Defining Immutable Objects

类不可变的条件之一是使其所有字段成为最终的和私有的。

为什么是决赛???其他条件都不充分?

【问题讨论】:

  • 仔细阅读:并非所有记录为“不可变”的类都遵循这些规则。
  • final 对线程安全有影响 - 请参阅这篇博文:jeremymanson.blogspot.co.nz/2008/04/immutability-in-java.html
  • 可以使用Class.getDeclaredField().set... 更改final 字段的值吗?我知道它可以用来改变私有字段的值。

标签: java private immutability final


【解决方案1】:

反问“为什么不是最终的?”。

final 意味着对于原始类型,一旦分配就无法更改值,这足以使它们不可变,

虽然对于非原始类型,一旦分配引用就无法更改(迈向不变性的第一步),您需要按照您共享的链接中所述执行更多操作。

【讨论】:

  • 但其他条件都足够了。
  • 因为您正在编写一个不可变的类,并且您确信一旦分配它就永远不会改变,因此受益于潜在的运行时优化和编译时内联
【解决方案2】:

根据不可变对象的定义(由 Wikipedia 提供)“在面向对象和函数式编程中,不可变对象是其状态在创建后无法修改的对象。”

一旦创建了最终对象,就不能重新分配它。如果没有最后的关键工作,您仍然可以在创建对象后对其进行更改。

另请参阅 final object in java

【讨论】:

  • 如果类是 final 并且它的字段是私有的并且没有定义 setter 并且我们不共享对可变对象的引用(例如通过 getter),则该类是不可变的......这些条件就足够了(不需要字段是最终的)。
  • 为什么不让编译器帮你检查呢?
  • 今晚我似乎在使用 Enter 键时遇到了一些困难。不可变的不同级别可能会使用也可能不会使用 final,我什至不会假装我理解它们。 Oracle 文档中“在某些情况下”为什么仅其他条件还不够的一个示例:“final 字段还允许程序员在不同步的情况下实现线程安全的不可变对象。” docs.oracle.com/javase/specs/jls/se7/html/… 对于一个可能比我自己更好的答案,请参阅stackoverflow.com/questions/16061030中的 assylias 回复
【解决方案3】:

链接文档的关键是这句话

并非所有记录为“不可变”的类都遵循这些规则....但是,此类策略需要复杂的分析并且不适合初学者。

这是针对初学者的教程。告诉他们“将所有内容设为私有和最终”会更容易,然后必须解释所有边缘情况以及如何正确处理可变引用并确保不要让您的引用逃逸。

【讨论】:

    【解决方案4】:

    如果其他条件可用,我们可以在不创建字段final 的情况下创建一个不可变的类/对象。

    但我认为final 在处理并发和同步时很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      相关资源
      最近更新 更多