Math类不可实例化,所有方法均为static且类被final修饰;支持double/float重载但无int/long专用版;返回值多为double,round返回long;需注意NaN、无穷等特殊值处理及浮点精度问题。

Math类不能实例化,所有方法都是静态的
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),在浮点比较中比==更可靠
替代方案:Java 8+ 的StrictMath和自定义封装
StrictMath提供严格可重现的计算结果(跨平台一致),但性能略低;而Math允许JVM用硬件指令优化,结果可能微异。普通业务用Math足够,金融或测试场景才需StrictMath。
立即学习“Java免费学习笔记(深入)”;
- 不要为了“看起来更安全”盲目换用
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传播——这两个点几乎每次代码审查都能揪出来。










