Java 基础类型int 与 Integer

本文详细解释了Java中int基础类型与Integer包装类的区别,包括它们的默认值、比较操作的结果差异,以及自动装箱和拆箱的过程。通过具体示例代码展示了不同情况下的对象比较行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 基础类型int 与 Integer

int与Integer区别

  • int是基础类型, Integer为对象并且为int的包装类
  • int的默认值为0, Integer为null

观察以下代码执行的结果

public static void main(String[] args) {
    int a1 = 127;
    Integer a2 = 127;
    System.out.println(a1 == a2); // true

    Integer b1 = 128;
    Integer b2 = 128;
    System.out.println(b1 == b2); // false
    
    Integer c1 = 127;
    Integer c2 = 127;
    System.out.println(c1 == c2); // true
}
复制代码

为什么三个判断出现的结果却不一样呢?这里就会提到自动拆箱与自动装箱两个概念。

自动装箱

将基础类型转换为包装类的对象称之为自动装箱。
当编译Integer a2 = 127 该语句的时候,其实将会自动的转换为如下语句

Integer a2 = Integer.valueOf(127);
复制代码

这时我们来看看valueOf(int i)该方法的源码做了什么事情,源码如下:
注意: 我的jdk版本为 1.7

/**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
复制代码

其主要的逻辑为

  • 判断传进来的值是否大于等于 IntegerCache.low 并且小于等于 IntegerCache.high
  • 满足该条件: 调用IntegerCache.cache 从IntegerCache缓存的cache数组里面取值并返回。
  • 不满足该条件: 创建一个Integer对象

这里涉及到了一个新的类叫IntegerCache,该类主要是缓存了一个Integer的数组,该数组存储了 -128至127 的Integer对象 我们现在来看一看 IntegerCache 这个类的源码,该类为一个静态的内部类,源码如下

/**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
复制代码

由上源码可以知道,IntegerCache 类的静态域里面执行了创建 -128到127 的Integer对象并将其放在了cache数组中。也就是说当 Integer a2 = 127 的时候,将会调用 Integer.valueOf(127) 方法,从而返回的是一个 Integer 对象。

自动拆箱

当Integer对象遇到与int类型的数据进行运算的时候,自动将Integer对象拆箱为int类型。
执行运算的时候,会调用 Integer对象的 intValue() 方法返回出内部的value,源码如下:

    /**
     * Returns the value of this {@code Integer} as an
     * {@code int}.
     */
    public int intValue() {
        return value;
    }
复制代码

示例解析

int a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
复制代码

a1为int 基础类型,a2 为Integer对象,a1 == a2 的时候,a2将会调用 intValue() 方法,此时为两个基础类型使用 == 故比对为 true

Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false
复制代码

b1为Integer对象,b2也为Integer对象,而且128超出了IntegerCache 所缓存的Integer对象,因此调用valueOf方法的时候是创建了两个不同的Integer对象,对象使用 ==进行比对的时候是判断的内存地址,因此为 false

Integer c1 = 127;
Integer c2 = 127;
System.out.println(c1 == c2); // true
复制代码

c1为Integer对象,c2也为Integer对象,但127未超出了IntegerCache 所缓存的Integer对象,因此调用valueOf方法的时候都是返回的IntegerCache所缓存的Integer对象,对象使用 ==进行比对的时候是判断的内存地址,但因为都是IntegerCache所缓存的Integer对象 因此为 true

转载于:https://juejin.im/post/5b4ef797e51d45194c0d0a7b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值