杰瑞科技汇

Java Integer 引用如何实现?

在 Java 中,Integer 是一个引用数据类型(它是一个类),用于包装基本数据类型 int,理解 Integer 的引用机制,通常需要关注以下几个核心知识点:对象引用传递自动装箱与拆箱Integer 缓存池以及比较操作( 与 equals

Java Integer 引用如何实现?-图1
(图片来源网络,侵删)

下面为你详细拆解:

作为引用传递(与基本类型 int 的区别)

  • 基本类型 int 是“值传递”,在方法中修改参数的值,不会影响外部的原始变量。
  • 引用类型 Integer 传递的是对象的地址(引用),因为 Integer 对象是不可变(Immutable)的,所以在方法内部修改它的值,实际上会创建一个新的对象,外部的原始引用依然指向原来的对象。

示例代码:

public class Main {
    public static void main(String[] args) {
        int a = 10;
        Integer b = 10;
        changeInt(a);
        changeInteger(b);
        System.out.println("基本类型 int a = " + a);       // 输出 10 (未改变)
        System.out.println("引用类型 Integer b = " + b);   // 输出 10 (未改变)
    }
    public static void changeInt(int num) {
        num = 20;
    }
    public static void changeInteger(Integer num) {
        // 这里的 num = 20 实际上是 num = Integer.valueOf(20)
        // 它让局部变量 num 指向了一个新的 Integer 对象,原来的对象没被修改
        num = 20; 
    }
}

自动装箱与拆箱

为了方便,Java 编译器会在 intInteger 之间自动转换:

  • 装箱:int 转成 Integer,底层调用 Integer.valueOf(int)
  • 拆箱:Integer 转成 int,底层调用 Integer.intValue()
Integer a = 10; // 自动装箱,底层: Integer a = Integer.valueOf(10);
int b = a;      // 自动拆箱,底层: int b = a.intValue();

核心考点:Integer 缓存池

这是 Java 中最容易踩坑的地方,为了提高性能和节省内存,Java 在 Integer 类中内置了一个缓存池,默认缓存了 -128 到 127 之间的 Integer 对象。

Java Integer 引用如何实现?-图2
(图片来源网络,侵删)

当你使用 Integer.valueOf(int) 或自动装箱时,如果数值在 -128 到 127 之间,Java 不会创建新对象,而是直接返回缓存池中的对象引用。

equals 的区别:

  • 比较两个引用是否指向同一个内存地址(同一个对象)。
  • equals:比较两个 Integer 包装的数值是否相等。

示例代码:

Integer x1 = 100;
Integer x2 = 100;
System.out.println(x1 == x2);      // true (都在缓存池中,指向同一个对象)
System.out.println(x1.equals(x2)); // true (数值相等)
Integer y1 = 200;
Integer y2 = 200;
System.out.println(y1 == y2);      // false (超出了缓存范围,每次都 new 了一个新对象)
System.out.println(y1.equals(y2)); // true (数值相等)
Integer z1 = new Integer(100);
Integer z2 = new Integer(100);
System.out.println(z1 == z2);      // false (只要 new 了,绝对是新对象)

空指针异常

因为 Integer 是一个引用类型,它的默认值是 null,如果对一个为 nullInteger 进行自动拆箱(转为 int 或进行数学运算),Java 会抛出 NullPointerException

Java Integer 引用如何实现?-图3
(图片来源网络,侵删)
Integer a = null;
int b = a; // 这里会触发自动拆箱 a.intValue(),抛出 NullPointerException

总结建议:

  1. 比较数值永远用 equals():不要用 来比较两个 Integer 对象的大小,除非你明确知道它们在缓存范围内,或者你需要比较它们是否是同一个对象。
  2. 注意方法的参数校验:如果方法的参数是 Integer,使用前最好判断一下是否为 null,防止拆箱报错。
  3. 优先使用基本类型 int:如果在局部变量或不需要用到集合类的地方,尽量使用 int,因为 Integer 会占用更多的内存,且有拆装箱的性能开销。
分享:
扫描分享到社交APP
上一篇
下一篇