Java 我可以在不可变类中使用StringBuilder吗

Java 我可以在不可变类中使用StringBuilder吗,java,string,immutability,Java,String,Immutability,如果我创建一个不可变的类。所有字段都必须是最终字段。如果我像这样使用stringbuilder 最终StringBuilder s=新StringBuilder(“你好”) ,则append函数可以追加s的值,并且类不会是不可变的。请注意。它是“浅不可变”的,因为您不能更改字段本身,但它不是完全不可变的-这意味着您几乎失去了与不可变相关的所有好处 基本上,为了实现不变性,所有的组成部分都必须是自然不可变的,或者有时你可以使用一些可变的东西,但是a)你构建了它,所以没有其他东西可以引用它;b) 你

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

,则append函数可以追加s的值,并且类不会是不可变的。请注意。

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

基本上,为了实现不变性,所有的组成部分都必须是自然不可变的,或者有时你可以使用一些可变的东西,但是a)你构建了它,所以没有其他东西可以引用它;b) 你从不暴露对它的引用;c) 你自己从来不会变异它


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

不确定为什么要将StringBuilder之类的类作为实例变量?它通常只在需要时创建,然后在生成字符串后丢弃。由于
StringBuilder
是对象的一部分,因此其状态是对象状态的一部分,并且可以修改(变异),这意味着对象根本不是不变的。不管它是否99%不可变,如果任何东西都可以变异,那么它就不是不可变的;但我认为这句话所能做的就是迷惑人们。应用这个标签有什么好处,而不是像@Andreas评论的那样简单地说“不”。@jaco0646:它最有用的是作为描述这种情况的一种简单方式。我看不出有任何迹象表明有人对此感到困惑。@jaco0646用教条式的“不”来回答这个问题是不实际的,因为在Java中基本上没有真正的不变性。您知道,您假设
String
是不可变的,但它只是数组的包装器,即使在最新的Java版本中,所有数组都是可变的。这同样适用于由数组支持的任何实现类,例如,
biginger
,反过来,
bigdecimic
,当大小至少为3时,通过(…)的
List.of(…)
Set.of(…)
或(…)创建的不可变集合,因此,任何非平凡的不可变类都可能是通过这个答案的a)到c)配方构造的,或者至少有“自然不可变”的组成部分,这些组成部分实际上是通过这个配方实现的…