Java中判断NaN应使用Float.isNaN()和Double.isNaN(),它们安全支持基本类型与包装类(需先判空防NPE);不推荐用v!=v自检;NaN具传染性,需在输入校验和关键计算前拦截;equals()中NaN被视为相等以保障集合去重。

Java 中 Float 和 Double 的 NaN(Not-a-Number)不能用 == 或 != 判断,因为根据 IEEE 754 规范,NaN == NaN 恒为 false。正确判断方式是使用其自带的静态方法或实例方法。
用 Float.isNaN() 和 Double.isNaN() 判断
这是最推荐、最安全的方式,适用于原始类型和包装类:
-
Float.isNaN(float f):传入float值(自动拆箱) -
Double.isNaN(double d):传入double值(自动拆箱) - 对
null的Float或Double对象需先判空,否则会抛NullPointerException
示例:
Float f = Float.NaN;
Double d = Double.NaN;
<p>System.out.println(Float.isNaN(f)); // true
System.out.println(Double.isNaN(d)); // true
System.out.println(Float.isNaN(0.0f)); // false</p><p>Float fNull = null;
// System.out.println(Float.isNaN(fNull)); // 报错!需先检查
if (fNull != null && Float.isNaN(fNull)) { ... }</p>用 value != value 自检(不推荐但可行)
利用 NaN 唯一的数学特性:NaN != NaN 为 true。可写成:
立即学习“Java免费学习笔记(深入)”;
float v = ...; if (v != v) { /* 是 NaN */ }double v = ...; if (v != v) { /* 是 NaN */ }
⚠️ 注意:仅适用于非 null 的基本类型变量;包装类必须先拆箱(如 f.floatValue() != f.floatValue()),且 null 会导致 NPE。
在计算中避免 NaN 传播或提前拦截
NaN 具有“传染性”:任何与 NaN 的算术运算结果仍是 NaN(如 NaN + 1、Math.sqrt(-1.0))。因此建议:
- 输入校验阶段就调用
isNaN()过滤异常值 - 关键计算前检查中间结果,例如:
double result = Math.sqrt(x); if (Double.isNaN(result)) { ... } - 使用
OptionalDouble或自定义封装来显式表达“无效数值”语义,而非依赖NaN
注意 NaN 的相等性与哈希行为
Float.NaN 和 Double.NaN 在 equals() 中被特殊约定为相等(即 Float.NaN.equals(Float.NaN) == true),且 hashCode() 也一致(Float.NaN.hashCode() == 0x7fc00000)。这与 == 行为不同,用于集合(如 HashSet)中能正确去重。
例如:Set<float> set = new HashSet(); set.add(Float.NaN); set.add(Float.NaN); // 最终 size 为 1</float>


















