杰瑞科技汇

Integer与int有何本质区别?

  • int基本数据类型,它不是一个对象。
  • Integerint包装类,它是一个对象。

下面我们从多个维度进行详细对比。

Integer与int有何本质区别?-图1
(图片来源网络,侵删)

核心区别对比

特性 int (基本数据类型) Integer (包装类)
本质 不是对象,是语言内置的简单数据类型。 是一个对象,是 java.lang 包下的一个 final 类。
内存占用 大小固定,在JVM中占 4个字节 作为对象,除了存储 int 值,还有对象头信息,占用空间更大。
默认值 在类中定义时,默认值为 0 在类中定义时,默认值为 null
功能 只能表示数值,不能调用方法。 提供了很多有用的方法,如 parseInt(), toString(), compareTo() 等。
使用场景 用于常规的数学计算,性能高。 需要对象的地方,如泛型集合、方法参数、可以为null的场景。
与null的关系 不能null 可以null

详细解释

int - 基本数据类型

int 是Java八种基本数据类型之一,用于存储整数值。

  • 内存效率高:因为它只是一个值,直接存储在栈内存中,没有额外的对象开销,所以计算速度非常快。
  • 不能为null:这是 int 最大的一个限制,在某些业务场景下,一个整数值可能“无意义”或“不存在”,这时用 int 就无法表示,数据库中的某个字段可能允许为空,但你无法用一个 int 变量来映射这个空值。
  • 没有方法:你不能对一个 int 变量调用任何方法。int a = 10; a.toString(); 是错误的编译。
public class IntExample {
    int myInt; // 在类中,默认值为 0
    public void test() {
        int number = 100;
        // number = null; // 编译错误!int类型不能赋值为null
        System.out.println(number); // 输出 100
    }
}

Integer - 包装类

Integer 类是 int 的一个“外壳”或“包装”,它将一个 int 值包装在一个对象中。

  • 是对象:作为对象,它可以被用在任何需要对象的地方。
  • 可以为null:这是它相对于 int 的最大优势,可以明确地表示“无值”或“缺失”的状态。
  • 提供丰富的工具方法Integer 类中包含了很多静态方法和实例方法,非常实用。
    • Integer.parseInt("123"):将字符串转换为 int
    • Integer.valueOf(123):将 int 转换为 Integer 对象。
    • i.toString():将 Integer 对象转换为字符串。
    • Integer.compare(a, b):比较两个整数的大小。
public class IntegerExample {
    Integer myInteger; // 在类中,默认值为 null
    public void test() {
        Integer number = 100; // 自动装箱
        System.out.println(number); // 输出 100
        System.out.println(number.toString()); // 输出 "100"
        System.out.println(myInteger); // 输出 null
        // 从字符串解析
        int parsedInt = Integer.parseInt("200");
        System.out.println(parsedInt); // 输出 200
    }
}

自动装箱 与 自动拆箱

为了方便开发者在基本类型和包装类之间切换,Java 5 引入了自动装箱自动拆箱机制。

自动装箱

当一个 int 类型的值被赋给一个 Integer 类型的变量时,JVM会自动将 int 值包装成一个 Integer 对象。

Integer与int有何本质区别?-图2
(图片来源网络,侵删)
// 在Java 5之前,需要手动装箱
Integer a = new Integer(10);
// Java 5之后,自动装箱
Integer b = 10; // 编译器会自动将其转换为: Integer b = Integer.valueOf(10);

自动拆箱

当一个 Integer 对象被用在需要 int 的地方(如数学运算、赋值给 int 变量)时,JVM会自动将 Integer 对象拆解为 int 值。

// 在Java 5之前,需要手动拆箱
int c = a.intValue();
// Java 5之后,自动拆箱
int d = b; // 编译器会自动将其转换为: int d = b.intValue();

示例:

Integer i = 10; // 自动装箱
i = i + 1;      // 1. 自动拆箱: i.intValue() + 1
                // 2. 计算: 10 + 1 = 11 (结果为int)
                // 3. 自动装箱: new Integer(11) 并赋值给 i
System.out.println(i); // 输出 11

重要注意事项:Integer 的缓存池

这是一个非常经典的面试考点,也是 Integer 使用中的一个“陷阱”。

为了提高性能和减少内存占用,Integer 类有一个内部缓存池,它缓存了 -128127 之间的 Integer 对象。

当你使用 Integer.valueOf(int i) 方法(自动装箱时会调用此方法)创建一个 Integer 对象时:

  • 如果值在 [-128, 127] 范围内,它会直接从缓存池中返回一个已经存在的对象,而不是创建一个新的。
  • 如果值超出这个范围,则会创建一个新的 Integer 对象。

示例:

Integer a = 100;
Integer b = 100;
System.out.println(a == b); // 输出 true
// 解释:a和b都指向缓存池中同一个 Integer 对象
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // 输出 false
// 解释:200 不在缓存池范围内,c和d是两个在堆上新创建的不同对象

vs equals()

  • 比较的是两个对象的内存地址(对于基本类型,比较的是值)。
  • equals()Integer 类重写了 equals() 方法,它比较的是两个 Integer 对象所包装的int值是否相等。
Integer e = 200;
Integer f = 200;
System.out.println(e == f);      // false (地址不同)
System.out.println(e.equals(f)); // true (值相同)

最佳实践:在比较两个 Integer 对象的值是否相等时,始终使用 equals() 方法,而不是 。


何时使用 int,何时使用 Integer

场景 推荐类型 原因
常规数学计算、循环计数器 int 性能最高,无对象开销。
需要将值存入 List, Set, Map 等集合 Integer 集合只能存储对象,不能存储基本类型。
方法参数或返回值可能为“无” Integer 可以用 null 来明确表示“无值”或“错误”。
处理数据库字段(可为NULL) Integer 直接对应数据库的 INT NULL 字段。
使用 int 作为Map的key int HashMap 的key可以是基本类型,JVM会自动装箱,但要注意,使用 Integer 作为key时,缓存池会影响结果。
  • int快速的、轻量级的,但功能有限,不能为 null
  • Integer灵活的、面向对象的,可以为 null,并提供了许多实用工具方法,但有性能和内存开销。
  • 自动装箱/拆箱 让两者之间的转换变得非常方便,但开发者需要理解其背后的机制,尤其是在 Integer 的缓存池和 比较方面,以避免潜在的 bug。

理解这两者的区别是写出健壮、高效Java代码的基础。

分享:
扫描分享到社交APP
上一篇
下一篇