众所周知,Integer
,Double
,Boolean
等类型包装是不可变的。但是,我无法在官方API文档中找到此文档,例如https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html。我还查看了源代码文件,并且不在评论中找到了这个。 (另一方面,String
源代码中的注释确实提到了它的不变性。)
这是因为:
- 它在其他地方记录(如果是,在哪里?),
- 这个事实也是如此着名的#34;或者
- 开发人员应该阅读包装器的实现并确定包装器是否是不可变的?
答案 0 :(得分:1)
值得考虑的是,不可变的意思是两件事:
a)如果你传递这个值,那么它就不会被改变。
b)“a”并且可以安全地在多线程环境中使用
ad A)有些类只是不可变但不是线程安全的,它们很适合与setter / getter一起使用并且是HashMap中的键 - 这些类没有mutator,所有字段都是私有的但没有所有字段final或者不稳定。
ad B)有些类是不可变的和线程安全的 - 这些类没有mutator,所有字段都是private和final或volatile。
线程安全的类通常在文档中甚至通过名称来描述,当然一些类可以是不可变的和/或线程安全的,但不是严格记录的。例如,String
类被记录为“常量”,但没有关于线程安全的信息 - 只有一个神秘的语句“因为String对象是不可变的,它们可以共享”但我认为这意味着不同的东西比...与其他线程共享。我们只知道流行类的属性,但我同意这些属性应该清楚地记录下来。在现实生活中不幸的是,他们不是。因此,了解类是否不可变的唯一方法是检查文档,如果没有足够的信息,则检查实现并询问作者他是否计划将来使该类变为可变。本主题在Java Concurrency in Practice一书中有所考虑,作者建议使用两个注释来表示某些内容是@ThreadSafe
和/或@Immutable
,但不幸的是,这不是一种常见的做法。 / p>
答案 1 :(得分:0)
盒装包装是“不可变的”,因为它们实际上是
可以在语法上与它们包装的文字类型互换。例如boolean
是不可变的:
boolean x = false;
x.flip(); // not implemented
大多数编程语言中的本机类型是不可变的。因此,通过包装契约,
Boolean x = false;
x.mutate(/* ??? */);
也未定义。