
Java 中使用 Long 包装类型时,== 比较的是对象引用而非数值,当数值超出 -128 到 127 缓存范围时,即使值相等也会因指向不同对象而返回 false。
java 中使用 `long` 包装类型时,`==` 比较的是对象引用而非数值,当数值超出 `-128` 到 `127` 缓存范围时,即使值相等也会因指向不同对象而返回 `false`。
在 Java 中,Long 是 long 的包装类,其对象创建涉及自动装箱(autoboxing)机制。当你写下:
Long x = (long)Math.pow(scn.nextLong(), 2); Long y = 2 * scn.nextLong();
编译器会自动将基本类型 long 装箱为 Long 对象。关键点在于:JVM 对 -128 至 127 之间的 Long 值进行了缓存重用(通过 Long.valueOf() 实现),但对更大数值(如 20000000000000000)每次都会新建对象。
因此,尽管 x 和 y 的数值完全相等(例如 x = y = 400000000000000000L),表达式 x == y 比较的是两个不同堆内存地址的对象引用,结果恒为 false。
而 x - y == 0 却返回 true,是因为该运算触发了自动拆箱:x 和 y 在参与算术运算前被隐式转为基本类型 long,此时比较的是原始数值,自然准确。
立即学习“Java免费学习笔记(深入)”;
✅ 正确做法有以下两种:
方案一:使用 equals() 进行值比较(推荐用于包装类型)
System.out.println(x.equals(y) ? "YES" : "NO");
注意:equals() 可安全处理 null(需额外判空),且语义明确——比较逻辑值。
方案二:直接使用基本类型 long(更高效、无装箱开销)
long x = (long) Math.pow(scn.nextLong(), 2); long y = 2 * scn.nextLong(); System.out.println(x == y ? "YES" : "NO"); // ✅ 此时 == 比较的是数值
⚠️ 补充注意事项:
- Math.pow() 返回 double,强制转 long 可能因浮点精度丢失引发错误(如 Math.pow(100000000L, 2) 可能得 9999999999999999L)。建议改用 BigInteger 或手动乘法(n * n)保证整数精度。
- 所有整数包装类(Integer, Short, Byte, Character)均有类似缓存机制,Long 缓存范围固定为 -128~127(不可配置),切勿依赖 == 判断包装类型相等性。
总结:在 Java 中,永远不要用 == 比较包装类型的相等性;应坚持“基本类型用 ==,引用类型用 .equals()”原则,并优先考虑避免不必要的装箱以提升性能与可读性。


















