关于 Integer 的一个坑
其实 JDK 中有很多小坑, 我们稍微不注意, 就掉进去了, 然后调了半天 bug, 也不知道为何. 很闹心!
这里说一下, 在Integer中的一个小坑.
看一个小例子:
@Test
public void testInteger(){
Integer a = 1;
Integer b = 1;
Integer c = 128;
Integer d = 128;
System.out.println(a == b); //true
System.out.println(c == d); //false
}
运行可以看到输出结果, 就是注释. 可以看到两个 128 尽然不相等! 闹什么呢? 逗我呢?
别着急, 先来看看执行 Integer a = 1; 之后 Integer 会做什么. 从JDK5 之后就有自动装箱和拆箱了. 给 Integer 赋值一个 int 数字, 当然会发生自动装箱, 封装成一个 Integer 对象.
怎么封装的呢? 在编译的时候, 会调用 Integer 中的 public static Integer valueOf(int 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: 这是可配置的项(-Djava.lang.Integer.IntegerCache.high=200), 默认的值是 127
在编译阶段, 如果将原始类型 int赋值给Integer, 编译时, 就会自动的调用Integer中的valueOf(int)方法(自动装箱)
也就是说:
1. 如果Integer的值在 -128与127之间, 那么这个值就会被缓存, 当你取这个值的时候, Integer类从缓存中取出来直接返回, 比较的是数字.
2. 如果Integer的值不在 -128与127之间, 那么当你取这个值得时候, Integer会为你new一个新对象出来, 这时候比较的是地址, 所以是false
扩展:
1. Boolean类型的两个值 true和false都会白cache.
2. Byte的256个值全部cache在内存中.
3. Short, Long两种类型的cache范围同Integer, 但是不同的是无法调整他们的大小, 代码中完全写死.
4. Float, Double 没有 cache, 在实际场景中 cache 需要自己做.
5. 当 Integer 与 int 类型比较时, 这时候会将Integer自动转换为int类型, 也就是通过调用 intValue()方法返回数字, 直接比较数字, 不会出现例子中的问题.
6. Integer 做 > >= < <= 比较的时候, Integer会自动拆箱, 就是比较他们的数字值.
7. switch case 为选择语句, 匹配的时候不会用 equals(), 而是直接用 "==", 而在 switch case语句中, 语法层次面 case部分是不能写 Integer 对象的, 只能是普通数字, 如果是普通的数字就会将传入的Integer自动拆箱. 所以不会出现例子中的问题.
@Test
public void testSwitchCase(){
Integer i = new Integer(3);
switch (i) {
case 2:
System.out.println("1");
break;
default:
break;
}
}
case 2: 不能写为 case i:
关于 Integer 的一个坑的更多相关文章
- 用html5的视频元素所遇到的第一个坑
html5 有一个video标签,这个是被大家所熟知的事情.按照w3c的规范,我认真的写出如下代码: <video preload="auto" controls=" ...
- 监控jvm的一个坑
监控jvm的一个坑 1,遇到的问题 我按照以往文档,在catalina.sh里追加jvm的监控api,如下 紧接着我启动 tomcat. 未报任何错误. 发现 lsof –i:12000, 12000 ...
- JavaScript中sort方法的一个坑(leetcode 179. Largest Number)
在做 Largest Number 这道题之前,我对 sort 方法的用法是非常自信的.我很清楚不传比较因子的排序会根据元素字典序(字符串的UNICODE码位点)来排,如果要根据大小排序,需要传入一个 ...
- PHP中逻辑运算符and/or与||/&&的一个坑
我原来以为PHP中的and和&&是一样的, 只是写法上为了可读性和美观, 事实上我错了. 这里面深藏了一个坑! 看以下代码: $bA = true; $bB = false; $b1 ...
- 困扰多日的C#调用Haskell问题竟然是Windows的一个坑
最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...
- 在VS2012中GridView的一个坑
使用GridView的时候遇到了一个坑,一个增加一个选择按钮~貌似在某些情况下会出现一个是否允许选择的属性,貌似会默认为fals,然后就返回不了指定ID!坑,巨坑!但是今天居然找不到这个属性了,难道是 ...
- 【转载】linux命令行计算器bc的一个“坑”
[转载自]http://blog.chinaunix.net/uid-174325-id-3518953.html 结论:ibase,obase可以使用在不同的计算公式里,但是尽量把obase放iba ...
- 使用ffmpeg视频编码过程中踩的一个坑
今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果: ...
- Jquery-全选和取消的一个坑
在做一个商城的购物车的时候遇到了一个坑, 购物车一般都有全选按钮, 再次点击就会全部消除, 在网上查到的答案全部都是使用attr来做的, 无一例外都不能用, 之后才知道要使用jquery的prop和r ...
随机推荐
- Troubleshooting a node by using the netapp SP
Troubleshooting a node by using the SP When you encounter a problem with a node, you can use the SP ...
- 营业额统计(SBT)
营业额统计(SBT) #include<cstdio> #include<cstring> #include<string> #include<cstdlib ...
- DDGSpring2016 Demos
I followed the course http://brickisland.net/DDGSpring2016/, and here is the screenshot of my coding ...
- xcode中使用xib添加autolayout中constrain to margins的不同
在使用xcode7 在storyboard中添加autolayout中发现 如果添加在view 直接添加到viewcontroller的view 上 constrain to margins 只 ...
- SQLServer2005删除log文件和清空日志的方案
数据库在使用过程中会使日志文件不断增加,使得数据库的性能下降,并且占用大量的磁盘空间.SQL Server数据库都有log文件,log文件记录用户对数据库修改的操作.可以通过直接删除log文件和清空日 ...
- Underscore.js基础入门
公司产品集成了对Underscore.js,所以需要对这个库有一定的了解.通过查阅资料,发现这个库主是对Array和JSON的处理支持.通过Underscore.js库,可以方便的对Array和JSO ...
- Codeforces 732D [二分 ][贪心]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: n天进行m科考试,每科考试需要a的复习时间,n天每天最多可以考一科.并且指定哪天考哪科. 注意考试那天不能复习. 问最少需要多少天可全部通过考试. ...
- 因为此控件已在 web.config 中注册并且与该页位于同一个目录中
在web.config文件配置了用户控件 <pages> <controls> <add tagPrefix="my" tagName="l ...
- AX 2012 两种lookup 的显示方式
第一种:只能单选的lookup: 代码: public void BusinessUnitLookup(FormStringControl _formstrcontroll) { //OMOperat ...
- [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")
javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢? 原因在于: ...