深层解析int,Integer(new和不new)相互之间的比较

28365365体育在线备用 🌸 2025-07-18 07:47:35 🎨 admin 👁️ 4333 ❤️ 814
深层解析int,Integer(new和不new)相互之间的比较

可以尝试以下两组比较的输出,看看是否符合预期答案:

第一组:

int a =127;

Integer b1=127;

Integer b2=127;

Integer c= new Integer(127);

System.out.println(a==b1);

System.out.println(a==c);

System.out.println(b1==c);

System.out.println(b1==b2);

第二组:

int aa =128;

Integer bb1=128;

Integer bb2=128;

Integer cc= new Integer(128);

System.out.println(aa==bb1);

System.out.println(aa==cc);

System.out.println(bb1==cc);

System.out.println(bb1==bb2);

答案揭晓:

第一组答案是

true

true

false

true

第二组答案是

true

true

false

false

其实如果只是想知道比较方法那很简单,我见过类似这样的总结(当然,这些结论都没错):

1.Integer与new Integer一定不会相等

2.两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false

3.两个都是new出来的,则为false

4.int和integer(new或非new)比较,都为true

眼睛:我会了

脑子:不,你不会 !

整理一下思路:

问题1 :==比较的是什么?

地址。

不完全对,Java的数据类型可以分为基本数据类型(如int)和引用数据类型(如Integer),对于后者来说,双等号代表比较地址,而对于前者来说,双等号代表数值(value)比较。

基本数据类型 == 基本数据类型 比较值

引用数据类型 == 引用数据类型 比较地址

那么有了问题2,

问题2:基本数据类型==引用数据类型,比较的又是什么

当然是比较值了。。。

例如在一个方法当中,int a=1,这是一个局部变量,局部变量存储在哪里呢?栈当中(方法执行就是出栈和入栈的过程),而Integer呢?对象,当然在堆当中,不论如何也不会是同一个地址。当然这只是一方面的理解。

换个角度,int是基本数据类型,我要求比较值,Integer是引用数据类型,你想比较地址。总之我俩要么都是基本数据类型,要么都是引用数据类型才能进行比较。

Integer实际上包含了一个int类型的成员变量,可以把这个成员直接拿过来使用,所以相比int转化为Integer,Integer还是选择妥协,向下兼容,最终变成了比较值,所以有了“自动拆箱”这个词。

很好理解。。。

继续

问题3:两个直接赋值没有new的Integer怎么比较

(建议到这里先看看文末的补充内容)

没new也是引用类型,当然要比较地址

值在-128-127范围内的,如果值相同,就是同一个对象(值不同,地址当然更不同)

值不在-128-127范围内的,地址一定不同;

Integer b1=127;

Integer b2=127;

Integer bb1=128;

Integer bb2=128;

System.out.println(b1==b2);//true

System.out.println(bb1==bb2);//false

Integer a=1 ;

1明明是一个int类型,你用Integer去声明它,应该报错才对,但是为了更好的进行数据转换,Java允许你这么声明,同时会将它自动装箱为Integer。在这种情况下, 如果a的值在-128-127范围内,就直接从默认的缓存中获取地址。

那如果不在这个范围内呢?就会new一个Integer对象(对此有疑问的直接跳到文章末尾看),即使两次值都一样,也是new出了两个对象,地址是不同的。

综上,不new直接复制的Integer,只要在-128-127这个范围内的,如果值相同,就是同一个对象(相同地址),值不同,地址也一定不同。

问题4:两个new过的Integer怎么比较

两个对象,两个地址

不可能相同!!!

这个不作解释了。。。

问题5:直接赋值不new和new了赋值的怎么比较

例如:

Integer b1=127;

Integer c= new Integer(127);

前面讲到,不new的情况下(b1),如果值在-128-127范围内,会从默认缓存中直接获取引用(或者说地址),此时b1存放于常量池当中,如果值不在这个范围内,会new一个Integer对象并将其存放于堆当中。一个在常量池(方法区),一个在堆当中,地址是不可能相同的。

这是不new的情况,new了又是什么情况?

对比普通实体类,new一个对象会调用它的构造方法,开辟新的内存空间,我们刚才说不new直接赋值的情况下:

如果a的值在-128-127范围内,存放于常量池,而new出来对象在堆当中,地址肯定是不一样的;

如果a的值不在-128-127范围内,会new一个新的对象存放于堆当中,而直接new出来对象也在堆当中,但是这是两个new出的对象,地址一定是不一样的;故而说:

new过的Integer和没new过的Integer这两者用双等号比较,结果一定是false。

补充:

自动装箱:

Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这相当于调用 valueOf 方法

比如 Integer i=1;这就完成了自动装箱

来看看这个valueOf方法写了什么:

/**

* 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) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

这里的low和high的初始化之后的值分别是-128和127

Integer中的静态内部类 IntegerCache——缓存

IntegerCache默认缓存了-128-127范围的整型;

当执行Integer i = 一个值时,如果这个值在-128-127这个缓存的范围内,就直接引用缓存中对应的地址,如果值不在这个范围内,就会new integer()一个对象。

相关推荐

如何正确调节相机对焦以获得清晰照片
28365365体育在线备用

如何正确调节相机对焦以获得清晰照片

📅 07-10 👁️ 6396
ppt音乐如何一直播放
det365娱乐官网登录

ppt音乐如何一直播放

📅 07-04 👁️ 6177