#底层原理&经典面试题--Integer类型的大小比较

(1)
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);

(2)
Integer i1 = 126;
Integer j1 = 126;
if(i1 == j1)
System.out.println(true);
System.out.println(true);

上面将各输出什么结果?
(1)true

(2)true true
我们来分析一下原理:
对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。底层代码如下:
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);
}
因此,当使用Integer x = y进行声明时,当y的值在-128127范围内时,实际上获取的是常量缓存区的值,这时相等的Integer对象都会共用一块内存地址,而不会开辟多个内存地址;当y的值在-128127范围外时,不管值相不相等都会开辟多个内存地址,而在比较引用类型时,==比较的是引用的地址,因此无论如何结果都是false;需要注意的是,如果是Integer x = new Integer(y),这种方式,那么不管值相不相等都会开辟多个内存地址,而在比较引用类型时,==比较的是引用的地址,因此无论如何结果都是false;

案例:
package com.yzh.maven.main;
public class Test {
public static void main(String[] args) {
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);

	Integer i1 = 126;
	Integer j1 = 126;
	if(i1 == j1)
		System.out.println(true);
	System.out.println(true);
	
	Integer i2 = 102;
	int i3 = 102;
	System.out.println(i2 == i3);
	
	Integer i4 = 172;
	int i5 = 172;
	System.out.println(i4 == i5);
	
	Integer i6 = 172;
	Integer i7 = 172;
	System.out.println(i6 == i7);//false
	
	
	Integer i8 = new Integer(100);
	Integer i9 = new Integer(100);
	System.out.println(i8 == i9);//false
	
	Integer i10 = new Integer(190);
	Integer i11 = new Integer(190);
	System.out.println(i10 == i11);//false
	
	System.out.println(i8.hashCode() == i9.hashCode());//true,hashcode相同,对象不一定相同
	/**
	 *    public int hashCode() {
     *	   	return value;
	 *	  }
	 *    private final int value;
	 *    public Integer(int value) {
		    this.value = value;
		  }
	 */
	
}

}

  其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
    我们分四种情况来讨论:
    1) Integer与int类型的赋值
    a. 把int类型赋值给Integer类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
     b. 把Integer类型赋值给int类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
    2) Integer与int类型的比较
     在这种方式中,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
    3) Integer之间的比较
     这个种方式是直接把两个引用的值(即是存储目标数据的那个地址)进行比较,无需再拆箱、装箱的过程。


Integer a1 = 160;
int a3 = 160;
System.out.println(a1++ == a3++);//true,会拆箱成int类型进行比较
Integer b1 = 150;
Integer b2 = 150;
Integer b3 = b1 + 1;
Integer b4 = b2 + 1;//还是Integer类型
System.out.println(b3 == b4);//flase

猜你喜欢

转载自blog.csdn.net/yzh18373476791/article/details/83949465