首页 > 编程语言 >什么是Java中的不可变类

什么是Java中的不可变类

时间:2024-11-07 11:34:11浏览次数:3  
标签:Java String 修改 对象 不可 变类 final

不可变类是指在创建后其状态(对象的字段)无法被修改的类。一旦对象被创建,它的所有属性都不能被更改,这种类的实例在整个生命周期内保持不变。

关键特征:

  1. 声明类为final,防止子类继承。
  2. 类的所有字段都是 private 和 final ,确保它们在初始化后不能被更改。
  3. 通过构造函数初始化所有的字段。
  4. 不提供任何修改对象状态的方法(如 setter 方法)。
  5. 如果类包含可变对象的引用,确保这些引用在对象外部无法被修改。例如 getter 方法中返回对象的副本( new 一个新的对象)来保护可变对象。

Java中的经典不可变类有:String 、Integer 、BigDecimal 、LocalDate 等。

扩展知识

不可变类的优缺点

优点:

  1. 线程安全:由于不可变对象的状态不能被修改,它们天生是线程安全的,在并发环境中无需同步。
  2. 缓存友好:不可变对象可以安全地被缓存和共享,如 String 的字符串常量池。
  3. 防止状态不一致:不可变类可以有效避免因意外修改对象状态而导致的不一致问题。

缺点:

  1. 性能问题:不可变对象需要在每次状态变化是创建新的对象,这可能会导致性能开销,尤其是对于大规模对象或频繁修改的场景(例如String频繁拼接)。

举例String

String就是典型的不可变类,当你创建一个 String 对象之后,这个对象就无法被修改。

因为无法被修改,所以像执行 s+="a";这样的方法,其实返回的是一个新建的 String 对象,老的 s 指向的对象不会发生改变,只是 s 的引用指向了新的对象而已。

所以不要在字符串拼接频繁的场景使用+来拼接,因为这条会频繁的创建对象。

不可变类的好处就是安全,因为知晓这个对象不可能会被修改,因此可以发放心大胆的用,在多线程环境下也是线程安全的。

如何实现一个不可变类?

具体按照前面的关键特征实现就行了。我们来看一下 String 的设计。

String类用 final 修饰,表示无法被继承。

String本质是一个 char 数组,然后用 final 修饰,不够 final 限制不了数组内部的数据,所以这还不够。

所以 value 是用 private 修饰的,并且没有暴露出 set 方法,这样外部其实就接触不到 value 所以无法修改。

当然还是有修改的需求,比如 replace 方法,所以这时候就需要返回一个新的对象来作为结果。

总结一下就是私有化变量,然后不要暴露 set 方法,即使有修改的需求也是返回一个新对象。

标签:Java,String,修改,对象,不可,变类,final
From: https://www.cnblogs.com/qimoxuan/p/18531827

相关文章

  • Java流程控制-顺序结构与选择结构
    顺序结构1.Java的基本结构就是顺序结构,除非特别明指,否则就按顺序一句一句执行。2.顺序结构是最简单的算法结构。3.语句与语句之间,框与框之间是按上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。选择结构if单选择结构......
  • Java面试系列-SpringCloud面试题20道,服务注册与发现,断路器,智能路由,熔断,追踪,网关,调用,限
    文章目录1.SpringCloud是什么?2.SpringCloud中的服务注册与发现是如何工作的?3.SpringCloud中的配置管理是如何工作的?4.SpringCloud中的断路器(Hystrix)是如何工作的?5.SpringCloud中的智能路由(Zuul)是如何工作的?6.SpringCloud中的服务熔断(Resilience4j)......
  • Java面试系列-MySQL面试题20道,InnoDB,索引类型,事务隔离级别,锁机制,MVCC,主从复制,慢查询,分
    文章目录1.MySQL中的InnoDB和MyISAM存储引擎有什么区别?2.MySQL中的索引类型有哪些?3.MySQL中的索引是如何工作的?4.MySQL中的事务隔离级别有哪些?5.MySQL中的锁机制有哪些?6.MySQL中的MVCC(多版本并发控制)是如何工作的?7.MySQL中的主从复制是如何工作的?8.MySQL中的分区......
  • JavaScript Kruskal 最小生成树 (MST) 算法(Kruskal’s Minimum Spanning Tree (MST) A
             对于加权、连通、无向图,最小生成树(MST)或最小权重生成树是权重小于或等于其他所有生成树权重的生成树。Kruskal算法简介:        在这里,我们将讨论Kruskal算法来查找给定加权图的MST。         在Kruskal算法中,按升序对给定图的所......
  • 158java ssm springboot基于Hive的大数据高校学生考试分析可视化系统考试评估(源码+文
         文章目录系列文章目录前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试四、代码参考源码获取前言......
  • 【转型必看】Java到AI,程序员的逆袭秘籍,转行人工智能不再是梦!
    随着技术的不断进步,人工智能(AI)已经成为当今科技领域最热门的话题之一。许多开发者开始考虑从传统的软件开发领域,如Java,转向人工智能领域,今天小编和大家一起来探讨Java开发者是否可以转型到人工智能,转型的优势,薪资对比,以及转型所需的知识和学习路线等。01Java开发者能否转......
  • 156java ssm springboot基于hive的大数据安顺旅游景点数据分析可视化系统旅游门票(源码
        文章目录系列文章目录前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试四、代码参考源码获取前言......
  • Java中的序列化和反序列化是什么
    序列化是将对象转换为字节流的过程,这样对象可以通过网络传输、持久化存储或者缓存。Java提供了java.io.Serializable接口来支持序列化,只要类实现这个接口,就可以将该类的对象进行序列化。反序列化是将字节流重新转换为对象的过程,即从存储中读取数据并重新创建对象。其他应用......
  • JavaScript中的this到底是什么?
    写在前面在JavaScript中,this关键字是一个非常重要的概念,它指向当前执行上下文中的对象。理解this的工作原理对于编写高效、可维护的JavaScript代码至关重要。本文将深入探讨this关键字的用法和规则。什么是this?this是一个特殊的关键字,在不同的上下文中可以指向不同的对象......
  • JavaScript中的变量作用域
    写在前面在JavaScript中,变量作用域是指变量在代码中可见的范围。理解变量作用域对于编写高效、可维护的JavaScript代码至关重要。本文将深入探讨JavaScript中的变量作用域,包括全局作用域、函数作用域和块级作用域。全局作用域在JavaScript中,任何在函数或块之外声明的变量......