自动装箱拆箱注意事项、了解Integer类缓存机制的“bug”

10 篇文章 0 订阅

自动装箱、拆箱的内幕:

自动装箱与拆箱的功能事实上是编译程序蜜糖( Compiler Sugar),也就是编译程序让你撰写程序时吃点甜头,编译时期根据所撰写的语法,决定是否进行装箱或拆箱动作。

                Integer num=1;//自动装箱,编译程序自动展开为:
		Integer localInteger=Integer.valueOf(1);

		int foo=num;//自动拆箱
		
		System.out.println(num+10);

num+10中先对num拆箱再进行运算。

Integer localInteger=Integer.valueOf(1);

这也是为基本类型建立打包器的方式之一。了解编译程序会如何装箱与拆箱是必要的,例如下面的程序是可以通过编译的

                Integer i=null;
		int j=i;
是在执行时期会有错误,因为编译程序会将之展开为
                Object localObject=null;
		int i=localObject.intValue();

在Java程序代码中,null代表一个特殊对象,任何类声明的参考名称都可以参考至null,表示该名称没有参考至任何对象实体,这相当于有个名牌没有任何人佩戴。在上例中,由于并没有参考至任何对象,所以就不可能操作
intValue方法,就相当于有个名牌没有人佩戴,你却要求戴名牌的人举手,这是一种错误.
编译程序蜜糖通常提供了方便性,但也因此隐藏了一些细节,所以别只顾着吃糖而忽略了该知道的概念。


                Integer num=100;
		Integer num1=100;
          if(num==num1) {
			System.out.println("num=num1");
			
		   }else {
			System.out.println("num!=num1");
		 }
如果只看就好像直接进行比较,有的人会理所当然回答显示
num=num1

那么下面这个:

            
                Integer num=200;
		Integer num1=200;
          if(num==num1) {
			System.out.println("num=num1");
			
		   }else {
			System.out.println("num!=num1");
		 }
程序代码只不过将100改为200,但执行结果会显示
num!=num1
前面提过,自动装箱是编译程序蜜糖。以上例来说,实际上会使用Integer.valueof()来建立Integer实例,所以你要知道

Integer.valueof()到底如何建立 Integer实例。查查JDK文件夹src.zip中的 java/lang文件夹中的 Integer.java,你会看到 :

public static Integer valueOf(int i) {
		
		if(i>=IntegerCache.low&&i>=IntegerCache.high)
			return IntegerCache.cache(i+(-IntegerCache.low));
		return new Integer(i);
		
	}
这段程序代码简单来说,就是如果传入的int在
IntegerCache.low和integerCache.high

之间,那就尝试看看前血缓存( Cache)中有没有打包过相同的值,如果有就直接返回,否则就使用new创建新的 Integer实例

IntegerCache.low
默认值是-128,
integerCache.high

默认值是127

 Integercache是 Integer类别内部实作中的一个类,缓存会在首次使用到 Integercache类时建立。


                Integer num=100;
		Integer num1=100;
第一行程序代码由于100在-128~127之间,会从缓存中传回 Integer实例,第二行程序代码执行时,要打包的同样是100,也是从缓存中返回同一 Integer实例,所以会参考到同一个 Integer实例,使用比较就会是true
如果是这个程序代码
                Integer num=200;
		Integer num1=200;
第一行程序代码由于200不在-128~127之间,所以直接建立 Integer实例,第二行程序代码执行时,也是直接建立新的 Integer实例,所以num1与num2不会参考到同一个 Integer实例,两个不同实例,使用==比较就会是false。
 Integercache.low默认值是-128, IntegerCache.high默认值是127 ,执行时期无法更改可以在启动JVM时,使用系统属性java. lang.Integer.IntegerCache.high来指定。java. lang.Integer.IntegerCache.high=300就会针对-128~300范围中建立的打包器进行快速存取.
在IDE中,也可以指定JVM启动时可用的一些自变量。例如在 Netbeans中,可以这样操作进行设定
(1)在项目上右击,在弹出的快捷菜单中选择“属性”命令,打开“项目属性”对话框在“类别”列表中选择“运行”节点
(2)单击“配置”列表框后面的“新建”按钮,打开“创建新的配置”对话框,在“配置名称”文本框中输入配置文件名称,然后单击“确定”按钮
(3)在“主类”文本框中输入与程序进入点的类完全吻合名称
(4)在“VM选项”文本框中输入- Djava. lang. Integer.IntegerCache.high=300,单击“确定”按钮完成设定
这样设定之后,每次在菜单中选择“运行”|“运行主项目”命令时,就会套用“VM选项”中的设定.
所以结论值比较时,别使用==或!=来比较两个对象实质内容值是否相同(因为与!=是比较对象参考),而要使用 equals()
 
                Integer num=200;
		Integer num1=200;
          if(num.equals(num2)) {
			System.out.println("num=num1");
			
		   }else {
			System.out.println("num!=num1");
		 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值