欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java语法int和Integer(== 和 equals的区别)

程序员文章站 2022-03-10 18:35:08
本篇文章先从一道题目开始 int a = 100; Integer b = 100; System.out.println(a == b); // true Integer a1 = 101; Integer b1 = 101; System.out.println(a1 == b1); // true Integer a2 = 200; Integer b2 = 200; System.out.println(a2 == b2);...

本篇文章先从一道题目开始

题目内容

    int a = 100;
    Integer b = 100;
    System.out.println(a == b); // true

    Integer a1 = 101;
    Integer b1 = 101;
    System.out.println(a1 == b1); // true

    Integer a2 = 200;
    Integer b2 = 200;
    System.out.println(a2 == b2); // false

以上的结果是否和你预期的一一致呢?如果都能正确的回答,说明对java的自动拆装箱和整数的缓存池有了一定的了解。

自动拆装箱,说的通俗易懂点就是基本类型和其包装类之间的相互转换

类型 类型转换 实现方法
装箱 int 转 Integer Integer x = Integer.valueOf(int value)
拆箱 Integer 转 int int y = x.intValue()

关于int 和 Integer之间的比较,Integer和Integer之间的比较,先看一下比较规则

比较规则

类型比较 比较规则
int 和 int == 比较的是值、无法使用equals比较
int 和 Integer 基本类型和包装类型, 会进行自动拆箱转为基础类型进行比较
Integer 和 Integer ==比较的是引用地址、equals比较的是值

在Integer 和 Integer 比较时,使用==比较的是引用地址,那么久涉及常量池(IntegerCache)的问题,分以下两种情况

1、 是否使用常量池

 - new Integer()构造方法, 不使用缓存池
 
 - Integer.valueOf()方法, 使用缓存池

2、大小是否在IntegerCache范围内

 - 在【-128 ~127】范围内,使用缓存池
 
 - 在【-128 ~127】范围外,不使用缓存池

看一下Integer的源码可知,IntegerCache是Integer的静态内部类
当使用valueOf()创建一个Integer时,
在[IntegerCache.low,IntegerCache.hign]闭区间范围内的,使用缓存池
否则使用new Integer(i)创建一个新的对象

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

IntegerCache.low=-128; IntegerCache.high =127

那么这个缓存池的范围可以修改吗?是可以的!

不过只能设置上限,下限是固定的-128

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) {
                try {
                    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);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

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

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

代码大致的内容:

读取java.lang.Integer.IntegerCache.high变量的值,如果不为空,和127比较大小Math.max(i, 127),将上限设置为两个中的最大值

然后初始化一个Integer数组,[-128, -127, -126, -125, -124,… 124, 125, 126, 127]

其中new Integer(j++) 是先赋值,再加一

基于以上的结论和认识,尝试做一下下面的比较

示例一
    Integer a3 = new Integer(121);
    Integer b3 = new Integer(121);
    System.out.println(a3 == b3); // false
    System.out.println(a3.equals(b3)); // true

    Integer a4 = new Integer(300);
    Integer b4 = new Integer(300);
    System.out.println(a4 == b4); // false
    System.out.println(a4.equals(b4)); // true
示例一解读:

首先new Integer()构造方法, 不使用缓存池,所以无需考虑范围

==比较的是引用地址,创建了两个对象,所以是false

equals比较的是值,所以是true

很多人好奇为什么equale比较的是值,这个可以看一下Integer的源码
java语法int和Integer(==  和 equals的区别)


示例二
    Integer a5 = Integer.valueOf(122);
    Integer b5 = Integer.valueOf(122);
    System.out.println(a5 == b5); // true
    System.out.println(a5.equals(b5)); // true

    Integer a6 = Integer.valueOf(500);
    Integer b6 = Integer.valueOf(500);
    System.out.println(a6 == b6); // false
    System.out.println(a6.equals(b6)); // true
示例二解读:

Integer.valueOf()方法, 使用缓存池,使用缓存池,就需要看大小是否在IntegerCache范围内,122在缓存池范围内,500不再缓存池范围内

==比较的是引用地址,使用缓存池创建的a5和b5,实际上是同一个对象,所以是true,a6和b6的大小不再范围内,不适用缓存池,所以创建了两个对象,所以是fasle

equals比较的是值,所以是true


示例三
    Integer a7 = Integer.valueOf(133);
    Integer b7 = new Integer(133);
    System.out.println(a7 == b7); // false
    System.out.println(a7.equals(b7)); // true
示例三解读:

Integer.valueOf() 方法使用缓存池,且133在【-128 ~127】范围内,a7变量指向常量池中的133
new Integer() 构造方法不使用缓存池,b7指向堆内存中的133对象,两个对象不是同一个,所以a7 == b为false

equals比较的是值,所以是true


如果对以上的还有疑惑,重新看上面的比较规则;

本文地址:https://blog.csdn.net/m761383058/article/details/112604769

相关标签: JAVA