Java中有哪些类的对象是不可变的
不可变类定义
可变类(Immutable Class)是指类的实例在创建之后其状态就不能被修改。换句话说,一旦创建了一个不可变类的对象,它的所有字段都将保持初始化时的值,并且不能通过该对象的方法来改变这些值
重要的特点
- 状态不变:一旦对象被创建,其状态(即对象内部字段的值)就不能被改变。
- 线程安全:由于不可变对象的状态不会改变,所以它们自然就是线程安全的。多个线程可以共享同一个不可变对象,而无需担心数据竞争或同步问题。
- 简化编程模型:不可变类减少了出错的可能性,因为它们的状态不会意外地被改变。这有助于编写更可靠、更易于维护的代码。
- 易于缓存和共享:由于不可变对象的状态不会改变,它们可以安全地用作缓存或共享数据。这有助于减少内存消耗,并提高应用程序的性能。
- 作为构建块:不可变类可以作为构建更复杂数据结构的基础,因为它们提供了稳定的、不会变化的组件。
常见的不可变类
- 基本类型的包装类: Java的八个基本数据类型(byte, short, int, long, float, double, char, boolean)的包装类(Byte, Short, Integer, Long, Float, Double, Character, Boolean)都是不可变的。这意味着当你创建一个这些类型的对象后,你不能改变其内部的值。
- String类: String类也是不可变的。当你对String对象进行修改时(如拼接操作),实际上Java会创建一个新的String对象,而不是修改原有的对象。
- 不可变的集合类
Java集合框架提供了一些不可变的集合实现,如
Collections.unmodifiableList()
、Collections.unmodifiableSet()
等。这些方法返回的是原有集合的不可变视图,任何对它们的修改操作都会抛出UnsupportedOperationException
异常 - 枚举类 在Java中,大多数枚举类也是不可变的。枚举类型的实例在JVM中只有一个,且不能被修改。
- 其他常用不可变类:
除了上述的这些类型外,Java中还有其他一些常用的不可变类,如BigDecimal、BigInteger等。此外,
java.lang.StackTraceElement
用于构建异常的堆栈跟踪,也是不可变的。
自定义不可变类通常需要遵循以下原则
- 将所有字段设置为
final
,以确保它们只能在构造函数中初始化一次。 - 不提供任何可以修改对象状态的方法(即没有setter方法)。
- 如果类包含对其他可变对象的引用,那么这些引用也应该被封装为不可变对象或提供只读的访问方式。
小结
需要注意的是,虽然这些类本身是不可变的,但它们可能包含对其他可变对象的引用。因此,在使用这些不可变类时,还需要注意它们所引用的对象是否也是不可变的。
不可变类在Java编程中有许多优点,如线程安全性、数据一致性、高效的对象拷贝和缓存等。它们在某些场景下(如并发编程、缓存等)特别有用。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-04-23,如有侵权请联系 cloudcommunity@tencent 删除缓存对象集合线程安全java