【问题标题】:Can I have StringBuilder in an immutable class我可以在不可变类中使用 StringBuilder
【发布时间】:2019-09-18 03:59:08
【问题描述】:

如果我创建一个不可变的类。所有字段都必须是最终的。如果我像这样使用 stringbuilder final StringBuilder s = new StringBuilder("你好");

,那么 append 函数可以附加 s 的值,并且类不会是不可变的。请指教。

【问题讨论】:

  • 不知道为什么要像 StringBuilder 这样的类作为实例变量?它主要只在需要时创建,然后在构建字符串后丢弃。
  • 由于 StringBuilder 是对象的一部分,它的 state 是您的对象 state 的一部分,并且因为它可以被修改(变异),这意味着您的对象根本不是不可变的。不管它是否 99% 是不可变的,如果任何东西都可以变异,那么它就不是不可变的

标签: java string immutability


【解决方案1】:

它是“浅不可变”的,因为您不能更改字段本身,但它不是完全不可变的 - 这意味着您几乎失去了与不可变相关的所有好处。

基本上要实现不变性,所有组成部分必须自然不可变,或者有时您可以使用可变的东西但a)您构建它,所以没有其他东西可以引用它; b) 你从不公开对它的引用; c) 你永远不会自己改变它。

例如,您可以编写一个使用 java.util.Date 的不可变类型(尽管我强烈建议使用 java.time) - 您只需要确保如果您想从方法返回日期,您克隆了它而不是返回该字段的值。

【讨论】:

  • 显然,shallow immutable 是一个东西;但我认为这句话所能做的就是迷惑人们。应用该标签有什么好处,而不是像@Andreas 评论的那样简单地说 no
  • @jaco0646:它主要作为一种描述这种情况的简单方式很有用。不过,我没有看到任何迹象表明有人对此感到困惑。
  • @jaco0646 用教条式的“不”来回答这个问题根本不切实际,因为这样的话,Java 中基本上没有真正的不变性。你知道,你假设String 是不可变的,但它只是一个数组的包装器,即使在最新的 Java 版本中,所有数组都是可变的。这同样适用于由数组支持的任何实现类,例如,BigInteger,反过来,BigDecimal,当大小至少为三时,通过List.of(…)Set.of(…)Map.of(…) 创建的不可变集合,等等。
  • 因此,任何重要的不可变类都可能通过此答案的 a) 到 c) 配方构建,或者至少具有通过该配方实际实现的“自然不可变”组成部分……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-11
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
相关资源
最近更新 更多