Integer的不相等问题

本文讲解步骤:

  1. 需要掌握的基础(不讲,只是概述)
  2. 使用自动装箱的不相等问题

0. 问题引出

@Test
public void test() {
	Integer i1 = 127;
	Integer i2 = 127;
	System.out.println(i1 == i2); // true
	Integer i3 = 128;
	Integer i4 = 128;
	System.out.println(i3 == i4); // false
    Integer i5 = new Integer(127);
    System.out.println(i1 == i5); // false
}

1. 概述

  1. 在Java中声明Integer的几种方式
public class Demo {
	public static void main(String[] args) {
		Integer i1 = 1;				// 自动装箱
		Integer i2 = new Integer(1);// 手动装箱
		int i3 = i2;				// 自动拆箱
		int i4 = i1.intValue(); 	// 手动拆箱
	}
}

  1. 基本类型的自动拆箱与装箱:
public class Demo {
	public static void main(String[] args) {
		// 拆箱
		Integer i1 = 1;
		int i2 = i1;
		System.out.println(i2);

		// 装箱
		int i3 = 1;
		Integer i4 = i3;
		System.out.println(i4);
	}
}

2. 使用自动装箱的不相等问题

因为有Java原生语法的支持,所以包装类型可以这样声明。

public class Demo {
	public static void main(String[] args) {
		Integer i1 = 1;				// 自动装箱
	}
}

但是,包装类型的本质就是引用类型。


Integer类结构:
在这里插入图片描述

在Java中,每个值都有其对应的内存地址。而内存地址要么是JVM分配,要么是new关键字开辟的。那么原生语法支持的背后是如何开辟内存的?JVM分配?new关键字?

其实,原生语法支持的背后就是调用的Integer.valueOf()方法,看不懂方法签名的可以点击这篇博文
在这里插入图片描述

那么打开Integer.valueOf()方法浏览一番
在这里插入图片描述
很简单明了,if语句中涉及到了IntegerCache类,比较了IntegerCache中的两个属性,按照翻译的中文意思来讲,此语句的作用是判断参数i的值是否包含在-128~127之间,在的话就返回缓存的值。点击IntegerCache类中看看。

在这里插入图片描述
的确,low的值为-128。

在这里插入图片描述
看注释得知,该类会在第一次使用Integer时就初始化了。

那么根据前文,使用自动装箱会调用Integer.valueOf(i)方法或手动调用Integer.valueOf(i)方法,那么IntegerCache类就会初始化。
在这里插入图片描述

当第一次使用该类,类中的静态代码块就会执行一次。
如何算使用该类呢?分为如下几种情况:
在这里插入图片描述
然后根据类的加载机制:
在这里插入图片描述
类加载进虚拟机时会调用static代码块(静态代码块),此时static代码块执行。

high值可以通过属性配置,此文不教如何配置(其实我也不会)。那么high值一般我们是没有配置的,所以integerCacheHighPropValue返回的是nullhigh就被赋值了h。然后for语句就循环257次生成256个Integer对象,并将其储存在缓存数组中。

最后,初始化完了IntegerCache类,根据参数从IntegerCache类的cache缓存数组中获取缓存的Integer对象,或new一个新的Integer对象。

@Test
public void test() {
	Integer i1 = 127;	// Integer.valueOf(127); 在缓存范围内,取缓存数组中的Integer对象
	Integer i2 = 127;	// Integer.valueOf(127); 在缓存范围内,取缓存数组中的Integer对象
	System.out.println(i1 == i2); // true
	Integer i3 = 128;	// Integer.valueOf(128); 不在存范围中,new一个新的Integer对象
	Integer i4 = 128;	// Integer.valueOf(128); 不在存范围中,new一个新的Integer对象
	System.out.println(i3 == i4); // false
    Integer i5 = new Integer(127); // 手动装箱,自己开辟一个新地址,不用缓存数组中的Integer对象
    System.out.println(i1 == i5); // false
}

手动装箱128Integer.valueOf(128)是一模一样的。

public class Demo {
	public static void main(String[] args) {
		Integer i1 = new Integer(128);				// 手动装箱
		Integer i2 = Integer.valueOf(128);			// 自动装箱
		System.out.println(i1 == i2); 				// false
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值