杰瑞科技汇

java int和integer

一句话概括

  • int: 是 Java 的一种基本数据类型,它不是对象,只是一个用来存储整数值的容器,直接存储数值本身。
  • Integer: 是 int 对应的包装类,它是一个对象,内部封装了一个 int 类型的值,并提供了一系列有用的方法(如 parseInt(), toString() 等)。

详细对比表格

特性 int (基本数据类型) Integer (包装类)
本质 不是对象,是语言内置的原始类型。 是对象,是 java.lang 包中的一个类。
存储 直接存储数值本身 在堆内存中创建对象,对象内部存储一个 int 类型的值。
默认值 0 null (非常重要!)
方法 没有,不能调用任何方法。 有很多静态方法和实例方法,如 parseInt(), toString(), compareTo() 等。
集合支持 不能直接放入 ArrayList, HashMap 等集合中,集合只能存对象。 可以直接放入集合中。
性能 占用内存小,计算速度快。 占用内存大(对象头 + 数据),创建和销毁有额外开销。
装箱/拆箱 - 支持自动装箱自动拆箱
大小 固定大小,为 32 位,有范围限制 (-2^312^31-1)。 大小不固定,取决于 JVM 和对象,但远大于 int

深入解析

int - 原始类型

int 是 Java 八种基本数据类型之一,它就像一个最简单的数字标签,用来表示整数。

特点:

  • 高效:因为直接在栈上分配内存,没有对象的开销,所以计算速度非常快。
  • 简单:它只有值,没有行为(方法)。

示例:

int age = 30; // 在栈上分配空间,直接存储值 30
age = age + 1; // 直接对值进行操作
// age.toString(); // 编译错误!int 没有方法

Integer - 包装类

Integer 类是为了让 int 这种基本类型也能以“对象”的形式存在而设计的,这在面向对象的编程中非常有用。

为什么需要包装类?

  1. 面向对象:Java 是一门面向对象的语言,很多核心功能(如集合框架)都要求操作的是对象,而不是基本类型。
  2. 提供实用方法Integer 类提供了很多静态方法来处理 int 类型,
    • Integer.parseInt("123"): 将字符串 "123" 转换为 int 类型的 123。
    • Integer.toString(123): 将 int 类型的 123 转换为字符串 "123"。
    • Integer.compare(a, b): 比较两个整数的大小。
  3. 支持 nullInteger 可以是 null,这在某些场景下非常有用,可以表示“无值”或“未知”,而 int 必须有值,其默认值是 0,这可能导致混淆(0 是一个有效的值,还是表示“未初始化”?)。

示例:

Integer score = new Integer(100); // 显式创建对象 (旧方式,不推荐)
Integer score = 100; // 自动装箱,现代 Java 推荐写法
// 使用 Integer 的方法
String strScore = score.toString(); // "100"
int primitiveScore = score; // 自动拆箱,将 Integer 对象转换回 int 值
// 在集合中使用
List<Integer> scores = new ArrayList<>();
scores.add(95); // 自动装箱,95 被包装成 Integer 对象后存入

核心概念:自动装箱与自动拆箱

这是 Java 5 引入的一个非常方便的特性,它让 intInteger 之间的转换变得透明,由编译器自动完成。

自动装箱

当一个 int 类型的值需要被赋给一个 Integer 类型的引用变量时,编译器会自动调用 Integer.valueOf() 方法,将其包装成一个 Integer 对象。

// 编译器看到的代码
Integer i = 10;
// 编译器实际生成的代码 (类似这样)
Integer i = Integer.valueOf(10);

自动拆箱

当一个 Integer 对象需要被用在需要一个 int 类型的地方时(如算术运算、赋值给 int 变量),编译器会自动调用 Integer.intValue() 方法,将其拆箱为 int 值。

// 编译器看到的代码
Integer i = 10;
int j = i + 5; // i 被自动拆箱
// 编译器实际生成的代码 (类似这样)
Integer i = Integer.valueOf(10);
int j = i.intValue() + 5;

自动装箱/拆箱的陷阱

这个“自动化”的特性也带来了一些容易出错的地方。

陷阱 1:NullPointerException

由于自动拆箱,Integer 对象是 null,那么在尝试将其转换为 int 时,就会抛出 NullPointerException

Integer count = null;
int primitiveCount = count; // 抛出 NullPointerException!
// 因为编译器会尝试执行 count.intValue(),而 null 对象没有 intValue() 方法。

陷阱 2:性能问题与对象缓存

IntegervalueOf() 方法对 -128127 之间的值做了缓存,这意味着:

Integer a = 127;
Integer b = 127;
System.out.println(a == b); // 输出 true,因为 a 和 b 指向同一个缓存对象
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // 输出 false,因为 128 不在缓存范围内,创建了两个新对象

注意: 比较的是对象的内存地址,对于 Integer,只有指向同一个对象时才为 true,要比较 Integer 对象中包裹的 int 值是否相等,应该使用 equals() 方法:

Integer x = 128;
Integer y = 128;
System.out.println(x.equals(y)); // 输出 true,比较的是值

选择使用 int 还是 Integer

这是一个非常实际的问题。

场景 推荐使用 原因
局部变量、方法参数、循环计数器 int 性能高,内存占用小,是绝大多数情况下的最佳选择。
需要表示“无值”或“未知” Integer Integer 可以是 null,而 int 不能,数据库查询可能返回某个值,也可能为空。
需要存入集合框架 Integer List, Set, Map 等集合只能存储对象。
需要调用 Integer 类的方法 Integer parseInt, toString, bitCount 等。
在泛型中使用 Integer 泛型类型参数(如 T)必须是对象类型,不能是基本类型。
  • int 是高效的、底层的数值工具,用于所有不需要对象特性的计算场景。
  • Integer 是面向对象的“外衣”,它让 int 能够融入对象世界(如集合),并提供了丰富的工具方法,同时支持 null 来表达“无”的概念。
  • 自动装箱/拆箱 是一座便利的桥梁,但开发者必须了解其背后的机制和潜在陷阱(如 NullPointerException 和缓存问题)。

理解这两者的区别,是迈向 Java 中高级开发的关键一步。

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