一、前言

在 Java 编程中,intInteger 是我们最常打交道的两种类型。
它们看似可以随意互转,但实际上存在很多潜在陷阱性能隐患

这篇文章带你系统梳理:

  • intInteger 的区别;
  • 两者互转时常见问题;
  • 如何避免空指针、比较错误与性能损耗。

二、基本概念:int vs Integer

对比项 int Integer
类型 基本数据类型 包装类(引用类型)
默认值 0 null
是否可为 null
是否可用于泛型
存储位置 栈内存 堆内存
比较方式 == 比较值 .equals() 比较值

示例:

int a = 10;          // 基本类型
Integer b = 10;      // 自动装箱(int → Integer)
int c = b;           // 自动拆箱(Integer → int)

从 Java 5 开始,Java 支持自动装箱与拆箱机制,使得 intInteger 可以相互赋值,看似方便,但背后有很多细节值得注意。


三、自动拆箱的空指针陷阱

最容易出问题的地方就是 NullPointerException(空指针异常)

Integer num = null;
int value = num;  // ❌ 自动拆箱时抛出 NullPointerException

为什么?
因为 Integer 是对象,null 不能被拆箱为 int

安全写法:

int value = (num != null) ? num : 0;

或者使用 Java 8 的 Optional

int value = Optional.ofNullable(num).orElse(0);

💡 建议:凡是涉及数据库取值或可能为 null 的包装类,都要防空处理!


四、自动装箱与拆箱的性能损耗

装箱和拆箱本质上是对象创建与方法调用,频繁执行会拖慢性能。

示例:

List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
    list.add(i);  // 自动装箱,创建100万个Integer对象
}

👉 如果在性能敏感的地方(如循环或计算逻辑中)使用包装类,
会带来 不必要的GC压力与性能开销

建议
能用 int 的地方,就不要用 Integer
仅在需要与泛型或对象交互时才使用包装类。


五、== 与 equals() 的比较陷阱

很多初学者都会被这段代码迷惑:

Integer a = 100;
Integer b = 100;
System.out.println(a == b);  // true ✅

Integer x = 200;
Integer y = 200;
System.out.println(x == y);  // false ❌

为什么?

Java 对 -128 ~ 127 范围内的 Integer 进行了缓存(IntegerCache)。
超出范围时,会创建新的对象,因此 == 比较会返回 false

正确做法:

System.out.println(x.equals(y)); // true ✅

🚨 小结:

  • == 比较的是“引用地址”;
  • .equals() 比较的是“数值内容”。

六、拆箱后的溢出问题

Integer 自动拆箱后参与运算,也会受到 int 的溢出限制。

Integer big = Integer.MAX_VALUE;
int result = big + 1;
System.out.println(result);  // 输出 -2147483648(发生溢出)

✅ 可使用 Math.addExact() 检查溢出:

int result = Math.addExact(big, 1); // 抛出 ArithmeticException

七、集合中的使用限制

Java 的集合类(如 ListMap)不支持基本类型,只能存放对象:

List<int> list = new ArrayList<>();  // ❌ 编译错误
List<Integer> list = new ArrayList<>(); // ✅ 正确

八、综合示例:Integer 转 int 的安全写法

下面是一段包含各种情况的完整示例:

public class IntegerDemo {
    public static void main(String[] args) {
        Integer num1 = 100;
        Integer num2 = 200;
        Integer num3 = null;

        // 安全拆箱
        int a = (num1 != null) ? num1 : 0;
        int b = (num3 != null) ? num3 : 0;

        System.out.println("a = " + a + ", b = " + b);

        // 比较陷阱
        System.out.println(num1 == 100);      // true
        System.out.println(num2 == 200);      // false
        System.out.println(num2.equals(200)); // true

        // 性能建议
        for (int i = 0; i < 3; i++) {
            process(i);  // 避免使用 Integer 包装类型
        }
    }

    public static void process(int x) {
        System.out.println("Processing: " + x);
    }
}

九、总结

场景 可能的问题 解决方案
自动拆箱 null → 空指针 判断或使用 Optional
频繁转换 性能下降 尽量用基本类型
比较数值 == 失效 使用 .equals()
大量数据 GC 压力大 减少装箱拆箱
集合操作 不支持基本类型 使用 Integer
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐