Math类不可实例化,所有方法均为static且类被final修饰;支持double/float重载但无int/long专用版;返回值多为double,round返回long;需注意NaN、无穷等特殊值处理及浮点精度问题。
Java的Math类是工具类,设计上禁止创建实例——它的构造函数是private的。直接调用静态方法即可,比如Math.abs(-5)、Math.sqrt(16)。如果写new Math(),编译器会报错:Math() has private access in Math。
static,不依赖对象状态final修饰,无法继承java.lang.Math默认可用Math里多数方法重载了double和float版本,但没有int或long专用版。传入整数会自动提升为double,返回值也基本是double(除round等少数几个)。
Math.pow(2, 3) → 返回double类型8.0,不是int
Math.round(2.6f) → 返回long;Math.round(2.6) → 也是long(注意不是int)Math.max(1, 2)有int、long、float、double四组重载,选对才能避免隐式转换开销System.out.println(Math.round(3.5)); // 输出 4L(long) System.out.println((int) Math.round(3.5)); // 需显式强转才得 int
Math方法遵循IEEE 754规范,对特殊值(如NaN、正/负无穷)有明确定义,但容易引发逻辑漏洞。例如Math.sqrt(-1)不抛异常,而是返回NaN;Math.log(-1)同样返回NaN。
Double.isNaN()或Double.isInfinite()必须主动检查,不能靠==判断NaN(因为NaN == NaN为false)Math.floor(-2.3) → -3.0,不是-2.0;向下取整不是“去小数部分”Math.ulp(1.0)返回最小单位值(2^-52),在浮点比较中比==更可靠StrictMath提供严格可重现的计算结果(跨平台一致),但性能略低;而Math允许JVM用硬件指令优化,结果可能微异。普通业务用Math足够,金融或测试场景才需StrictMath。
StrictMath
distance(x1,y1,x2,y2)内部直接用sqrt(pow(...)+pow(...))
Math.pow不适合——它走浮点路径,应自己写循环或用BigInteger.pow()
public static long intPow(int base, int exp) {
if (exp == 0) return 1;
long result = 1;
for (int i = 0; i < exp; i++) result *= base;
return result;
}
实际用的时候,最易出错的是把round当floor或ceil用,还有忘记NaN传播——这两个点几乎每次代码审查都能揪出来。