Java泛型不支持基本类型运算,需用<T extends Number>约束并调用doubleValue()等转换后计算;比较时结合Comparable接口,加减乘除等操作需手动拆箱、运算、装箱,避免直接使用+或>及==。

Java 泛型本身不支持基本类型运算(如 +、>),也不能直接对泛型类型做算术或比较操作。要实现通用数值工具类,核心思路是:**用包装类 + 类型约束 + 显式转换逻辑**,结合 `Number` 抽象基类和反射/方法引用规避类型擦除限制。
用 Number 作为上界约束泛型参数
所有数值包装类(Integer、Double、Long 等)都继承自 Number,因此可将泛型限定为 Number 子类,再通过 doubleValue() 或 longValue() 统一转为可运算的原始类型:
- 声明泛型为
<T extends Number>,确保传入的是合法数值包装类 - 避免使用
instanceof逐个判断类型,优先调用doubleValue()进行浮点计算(精度损失可控,覆盖整数和浮点) - 若需精确整数运算(如大数),可额外提供
<T extends BigInteger>重载,但不属于通用场景
实现安全的比较操作(Comparable + Number 双校验)
仅靠 Number 无法直接比较大小(比如 Integer 和 Double 混用时),应结合 Comparable 接口与运行时类型适配:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 泛型声明改为
<T extends Number & Comparable<T>>,强制要求类型自身可比较 - 对同类型值(如两个
Integer)直接调用compareTo() - 对异类型(如
Integer和Double)统一转为double后用Double.compare(),避免自动拆箱引发的NullPointerException
封装常用计算方法(加减乘除、最大最小值)
以加法为例,不依赖运算符重载,而是提取数值后计算再装箱:
立即学习“Java免费学习笔记(深入)”;
- 输入两个
T extends Number,调用a.doubleValue() + b.doubleValue() - 根据原始类型决定返回值:若原类型是
Integer,结果四舍五入转Integer;若是Double,直接返回Double;更稳妥做法是统一返回Double或由调用方指定目标类型 - 提供静态泛型方法,如
public static <T extends Number> Double add(T a, T b),清晰表达语义且避免装箱开销 - 除法需处理
0除数,抛出ArithmeticException并附带原始类型信息(如 “Division by zero in Integer division”)
避免常见陷阱
泛型数值工具易出错的关键点:
-
不要尝试对泛型变量直接使用
+或>—— 编译失败,不是运行时异常 -
慎用
==比较包装类 —— 应始终用equals()或compareTo(),尤其注意Integer缓存范围(-128~127) -
类型擦除导致无法获取泛型实际类 —— 若需实例化(如返回新对象),必须显式传入
Class<T>参数,或用工厂函数 -
NaN 和无穷大需特殊处理 —— 在比较和计算前用
Double.isNaN()/Double.isInfinite()检查

















