Skip to content

int 和 Integer 的区别

intInteger 在 Java 中的区别主要体现在性能、用途以及特性上。

在 Java 中,有 8 种原始数据类型(Primitive Types),分别是:booleanbyteshortcharintfloatdouble long。其中,int 是表示整数的基本数据类型。

Integerint 类型的包装类,它通过一个 int 类型的字段来存储数据,同时提供了一些实用的操作方法,如比较、转换和处理等。Integer 的存在使得基本类型可以作为对象使用,从而支持泛型、集合等功能。

装箱和拆箱

Java
package com.practice.app;

public class IntVsIntegerDemo {
    public static void main (String[] args) {
        int primitiveInt = 18; // 基本类型
        Integer wrapperInteger = 18; // 包装类型

        Integer autoBoxed = primitiveInt; // 自动装箱
        int autoUnboxed = wrapperInteger; // 自动拆箱
        System.out.println("自动装箱后的值: " + autoBoxed); // 输出: 自动装箱后的值: 18
        System.out.println("自动拆箱后的值: " + autoUnboxed); // 输出: 自动拆箱后的值: 18
    }
}

Java 会自动将 int 转换为 Integer(装箱),反之亦然(拆箱)。这是 intInteger 一大特性区别。

Integer 的值缓存

构建 Integer 对象的传统方式是直接调用构造器,直接 new 一个对象。在 Java 中有个静态工厂方法 valueOf,在调用它的时候会利用一个缓存机制,带来了明显的性能改进。这个值默认缓存是 -128127 之间。

Integer 超出缓存范围

Java
package com.practice.app;

public class IntVsIntegerDemo {
    public static void main (String[] args) {
        Integer a = 128;
        Integer b = 128;

        System.out.println("a == b: " + (a == b)); // 输出: a == b: false,引用不同
        System.out.println("a.equals(b): " + a.equals(b)); // 输出: a.equals(b): true,值相等
    }
}
  • == 对于 Integer 比较引用地址,而对 int 比较值。
  • 使用 equals 方法可以正确比较 Integer 的值。
  • Integer 缓存范围为 -128127,这里的 128 超出了范围,超出范围的值会创建新的对象。

Integer 缓存范围内

Java
package com.practice.app;

public class IntVsIntegerDemo {
    public static void main (String[] args) {
        Integer c = 127;
        Integer d = 127;

        System.out.println("c == d: " + (c == d)); // 输出: c == d: true,引用相同
        System.out.println("c.equals(d): " + c.equals(d)); // 输出: c.equals(d): true,值相等
    }
}
  • Integer 缓存范围为 -128127,这里的 127 在此范围内的值会共享同一个对象引用。

Null 值处理

Java
package com.practice.app;

public class IntVsIntegerDemo {
    public static void main (String[] args) {
        Integer nullableInteger = null;
        try {
            int nullInt = nullableInteger; // 会抛出 NullPointerException
        } catch (NullPointerException e) {
            System.out.println("NullPointerException 发生,因为尝试对 null 进行拆箱。");
        }
    }
}
  • int 不能为 null
  • Integer 可以为 null,但在拆箱时会抛出 NullPointerException

性能差异

Java
package com.practice.app;

public class IntVsIntegerDemo {
    public static void main(String[] args) {
        long start = System.nanoTime();
        int sumPrimitive = 0;
        for (int i = 0; i < 1000000; i++) {
            sumPrimitive += i;
        }
        long end = System.nanoTime();
        System.out.println("使用 int 的求和耗时: " + (end - start) + " 纳秒");
        // 输出:使用 int 的求和耗时: 4565600 纳秒

        start = System.nanoTime();
        Integer sumWrapper = 0;
        for (int i = 0; i < 1000000; i++) {
            sumWrapper += i; // 自动拆箱和装箱的性能开销
        }
        end = System.nanoTime();
        System.out.println("使用 Integer 的求和耗时: " + (end - start) + " 纳秒");
        // 输出:使用 Integer 的求和耗时: 18645400 纳秒
    }
}
  • int 是基本数据类型,性能高,适合性能敏感的场景。
  • Integer 是包装类型,额外的对象创建和自动装箱/拆箱可能会带来性能开销。

最后更新: