Math.abs() 和 Math.max() 因重载与隐式类型转换易返回意外结果:abs 无 byte 版本需提升为 int,max 混合 float/double 会升为 double 引发精度问题;Math.pow() 浮点误差可能导致整数幂结果偏差,小整数幂宜用位运算或连乘。
Java 的 Math 类所有方法都是静态的,不依赖实例,但类型匹配稍有不慎就会触发隐式转换或重载误选。比如 Math.abs(-128) 对 byte 直接写会编译失败——因为没有 abs(byte) 重载,必须先提升为 int;而 Math.max(3.5f, 4.2) 实际调用的是 max(double, double),float 被自动提升,可能带来精度混淆。
Math.abs(-128L) 用 long 版本,Math.abs(-128.0) 用 double 版本double,除非明确需要 float 节省内存且接受单精度误差Math.max() / Math.min() 不支持 null 或对象,传入引用类型会编译报错Math.pow(double, double) 返回 double,但底层用的是 IEEE 754 浮点运算,对整数幂(如 2^10)也可能出现 1023.9999999999999 这类结果,直接转 int 会截断成 1023。
1 比 Math.pow(2, 10) 更快更准
(int) Math.pow(x, y),改用 (int) Math.round(Math.pow(x, y))
BigInteger.pow(),Math.pow() 会溢出或失真double result = Math.pow(10, 2); // 返回 100.0(看似安全) double bad = Math.pow(5, 3); // 可能返回 124.99999999999999 int wrong = (int) bad; // 得到 124 int correct = (int) Math.round(bad); // 得到 125
Math.random() 返回的是伪随机 double(范围 [0.0, 1.0)),基于线程本地的 java.util.Random 实例,种子由系统时间初始化,可预测、不可重现、不具备密码学安全性。
[a, b])要小心边界:(int)(Math.random() * (b - a + 1)) + a,注意乘法后强制转 int 是向下取整Math.random() 内部锁可能导致性能抖动,应改用 ThreadLocalRandom.current().nextInt(a, b+1)
SecureRandom,Math.random() 绝对禁止这三个方法处理负数时行为不同,容易误用:Math.floor(-2.7) 是 -3.0(向下取整),Math.ceil(-2.7) 是 -2.0(向上取整),Math.round(-2.7) 是 -3(四舍五入,规则是加 0.5 后 floor)。
Math.round() 对 float 返回 int,对 double 返回 long,别忽略返回类型变化Math.trunc() 不存在,得用 (long)x 或 BigDecimal.valueOf(x).setScale(0, RoundingMode.DOWN)
Math.round(),它不满足银行家舍入(half-even)
BigDecimal 配合指定舍入模式System.out.println(Math.round(-2.5)); // -2(不是 -3!Java 的 round 使用“half up”规则) System.out.println(Math.floor(-2.5)); // -3.0 System.out.println(Math.ceil(-2.5)); // -2.0
实际项目里最容易被忽略的是类型隐式转换和负数取整规则——这两个点一旦出错,问题往往在生产环境才暴露,而且难以复现。