自动装箱 Integer a = 127 实际调用 Integer.valueOf(127),而 valueOf 对 −128 到 127 的整数从内部缓存(IntegerCache)返回同一个对象;超出范围才 new 新对象。因此 127 时 a、b 指向同一缓存实例,== 为 true;128 时是两个不同对象,== 为 false。缓存上界可通过 -XX:AutoBoxCacheMax 调整,下界固定 −128。
由此得到一条工程铁律:包装类型比较一律用 equals(或先拆箱),永远不用 ==。这一家族还包括 Byte、Short、Long、Character(0~127),Boolean 缓存 TRUE/FALSE。反例同样重要:equals 比较的是值,Integer(1000).equals(Long 型值) 为 false——equals 先检查类型,包装类型之间即使数值相等也不 equals,比较前要注意类型一致。追问方向:缓存发生在装箱而非 new Integer()(new 总是新对象,构造器已废弃)、自动拆箱的空指针陷阱(Integer 为 null 参与运算 NPE)、数据库查出的 Long 主键用 == 判等的线上事故案例。
(约 390 字)