标准 API 中一些著名的不可变类: java.lang.String(已经提到) 基本类型的包装类:java.lang.Integer、java.lang.Byte、java.lang.Character、java.lang.Short、java.lang.Boolean、java.lang.Long、java.lang.Double、 java.lang.Float java.lang.StackTraceElement(用于构建异常堆栈跟踪) 大多数枚举类是不可变的,但这实际上取决于具体情况。 (不要实现可变枚举,这有时会把你搞砸。)我认为至少标准 API 中的所有枚举类实际上都是不可变的。 java.math.BigInteger 和 java.math.BigDecimal(至少这些类本身的对象,子类可以引入可变性,尽管这不是一个好主意) java.io.文件。请注意,这表示 VM 外部的对象(本地系统上的文件),它可能存在也可能不存在,并且具有一些修改和查询此外部对象状态的方法。但是 File 对象本身保持不变。 (java.io 中的所有其他类都是可变的。) java.awt.Font - 表示在屏幕上绘制文本的字体(可能有一些可变的子类,但这肯定没有用) java.awt.BasicStroke - 用于在图形上下文中绘制线条的辅助对象 java.awt.Color -(至少是这个类的对象,一些子类可能是可变的或取决于一些外部因素(如系统颜色)),以及 java.awt.Paint 的大多数其他实现,如 java.awt.GradientPaint, java.awt.LinearGradientPaint java.awt.RadialGradientPaint, (我不确定 java.awt.TexturePaint) java.awt.Cursor - 表示鼠标光标的位图(这里也有一些子类可能是可变的或取决于外部因素) java.util.Locale - 代表 _特定的地理、政治或文化区域_。 java.util.UUID - 尽可能多的全局唯一标识符 虽然大多数集合是可变的,但 java.util.Collections 类中有一些包装方法,它们返回集合的不可修改视图。如果您向它们传递一个在任何地方都不知道的集合,这些实际上是不可变的集合。此外, Collections.singletonMap() , .singletonList , .singleton 返回不可变的单元素集合,也有不可变的。 java.net.URL 和 java.net.URI - 表示资源(在 Internet 或其他地方) java.net.Inet4Address 和 java.net.Inet6Address、java.net.InetSocketAddress 大多数 java.security.Permission 的子类(表示某些操作所需的权限或授予某些代码的权限),但不是 java.security.PermissionCollection 和子类。 java.time 的所有类除了 DateTimeException 是不可变的。 java.time 子包的大部分类也是不可变的。 可以说原始类型也是不可变的——您不能更改 42 的值,对吗? 类 AccessControlContext 是一个不可变的类 AccessControlContext 没有任何变异方法。它的状态由一个 ProtectionDomains 列表(这是一个不可变的类)和一个 DomainCombiner 组成。 DomainCombiner 是一个接口,因此原则上实现可以在每次调用时做不同的事情。 事实上,ProtectionDomain 的行为也可能取决于当前生效的策略——是否将这样的对象称为不可变对象是有争议的。 和访问控制器? 没有 AccessController 类型的对象,因为这是一个没有可访问构造函数的最终类。所有方法都是静态的。可以说 AccessController 既不是可变的也不是不可变的,或者两者兼而有之。 这同样适用于所有其他不能有对象(实例)的类,最著名的是: java.lang.Void java.lang.System(但这有一些可变的静态状态 - in , out , err ) java.lang.Math(这也是 - 随机数生成器) java.lang.reflect.数组 java.util.集合 java.util.数组 原文由 Paŭlo Ebermann 发布,翻译遵循 CC BY-SA 4.0 许可协议
标准 API 中一些著名的不可变类:
java.lang.String(已经提到)
基本类型的包装类:java.lang.Integer、java.lang.Byte、java.lang.Character、java.lang.Short、java.lang.Boolean、java.lang.Long、java.lang.Double、 java.lang.Float
java.lang.StackTraceElement(用于构建异常堆栈跟踪)
大多数枚举类是不可变的,但这实际上取决于具体情况。 (不要实现可变枚举,这有时会把你搞砸。)我认为至少标准 API 中的所有枚举类实际上都是不可变的。
java.math.BigInteger 和 java.math.BigDecimal(至少这些类本身的对象,子类可以引入可变性,尽管这不是一个好主意)
java.io.文件。请注意,这表示 VM 外部的对象(本地系统上的文件),它可能存在也可能不存在,并且具有一些修改和查询此外部对象状态的方法。但是 File 对象本身保持不变。 (java.io 中的所有其他类都是可变的。)
java.awt.Font - 表示在屏幕上绘制文本的字体(可能有一些可变的子类,但这肯定没有用)
java.awt.BasicStroke - 用于在图形上下文中绘制线条的辅助对象
java.awt.Color -(至少是这个类的对象,一些子类可能是可变的或取决于一些外部因素(如系统颜色)),以及 java.awt.Paint 的大多数其他实现,如
java.awt.Cursor - 表示鼠标光标的位图(这里也有一些子类可能是可变的或取决于外部因素)
java.util.Locale - 代表 _特定的地理、政治或文化区域_。
java.util.UUID - 尽可能多的全局唯一标识符
虽然大多数集合是可变的,但 java.util.Collections 类中有一些包装方法,它们返回集合的不可修改视图。如果您向它们传递一个在任何地方都不知道的集合,这些实际上是不可变的集合。此外,
Collections.singletonMap()
,.singletonList
,.singleton
返回不可变的单元素集合,也有不可变的。java.net.URL 和 java.net.URI - 表示资源(在 Internet 或其他地方)
java.net.Inet4Address 和 java.net.Inet6Address、java.net.InetSocketAddress
大多数 java.security.Permission 的子类(表示某些操作所需的权限或授予某些代码的权限),但不是 java.security.PermissionCollection 和子类。
java.time
的所有类除了DateTimeException
是不可变的。java.time
子包的大部分类也是不可变的。可以说原始类型也是不可变的——您不能更改 42 的值,对吗?
AccessControlContext 没有任何变异方法。它的状态由一个 ProtectionDomains 列表(这是一个不可变的类)和一个 DomainCombiner 组成。 DomainCombiner 是一个接口,因此原则上实现可以在每次调用时做不同的事情。
事实上,ProtectionDomain 的行为也可能取决于当前生效的策略——是否将这样的对象称为不可变对象是有争议的。
没有 AccessController 类型的对象,因为这是一个没有可访问构造函数的最终类。所有方法都是静态的。可以说 AccessController 既不是可变的也不是不可变的,或者两者兼而有之。
这同样适用于所有其他不能有对象(实例)的类,最著名的是:
in
,out
,err
)