Java基本类型无不可变概念,包装类(如Integer)通过private final字段和无修改方法实现不可变性,保障线程安全、缓存复用、HashMap键可靠性及语义一致性。

Java基本类型本身没有“可变”或“不可变”的概念——它们只是内存里一段固定大小的原始值,读写就是直接覆盖。真正谈不可变性,指的是包装类(如Integer、Boolean、Character等)的设计选择:这些类的对象一旦创建,内部封装的值就再也无法更改。
包装类不可变性的核心设计意图
不是技术做不到可变,而是主动放弃可变能力
所有包装类的内部字段都用private final修饰(比如Integer.value),构造后彻底锁定。没有setValue()之类的方法,任何“修改”操作(如i = i + 1)实际是新建一个对象并让变量指向它。服务于真实工程场景的稳定性需求
不可变不是为了炫技,而是解决几类关键问题:线程安全、缓存复用、集合行为可靠、语义一致。
不可变性在具体场景中如何起作用
多线程共享时天然安全
多个线程同时读取同一个Integer.valueOf(42)返回的对象,不会出现一个线程刚读到42、另一个线程把它改成99的情况。不需要synchronized或volatile,省去同步开销。缓存机制得以成立
IntegerCache默认缓存-128到127之间的实例。如果这些对象可变,某处代码执行someInt.setValue(-1000),所有引用该对象的地方都会看到突变——逻辑瞬间错乱。不可变性是缓存能放心复用的前提。作为HashMap的key不会失联
hashCode()和equals()结果由内部值决定。若允许改值,对象在哈希表里的桶位置就可能失效,导致map.get(key)查不到、set.contains(x)返回false,这类bug极难定位。匹配开发者对“值”的直觉
写int i = 5; i++,没人觉得是在“修改数字5本身”,而是理解为“得到新值6”。包装类延续这一语义:Integer i = 5; i++本质是i = Integer.valueOf(i.intValue() + 1)。这种一致性避免误用,比如不会有人幻想调用某个隐藏方法去“原地更新”一个Integer。
和基本类型、String的不可变逻辑一脉相承
-
int是原始值,改的是变量所指的值; -
Integer是对象,但设计成“看起来像值”——不提供修改入口,每次运算生成新实例; -
String同理:s += "x"不是修改原字符串,而是新建; - 三者共同点:状态固化 → 行为可预测 → 并发无需防护 → 集合中表现稳定。
不复杂但容易忽略
立即学习“Java免费学习笔记(深入)”;


















