个人博客: 斯科特安的时间
最近项目组使用findbugs辅助检测代码问题,其中一个问题提到了Integer对象的值比较问题。虽然心里很清楚,java语言类对象的双等号操作符默认比较的是对象的地址,即是否是同一个对象。可是对于Integer、Long这类基本类型的扩展类,心想存在特殊处理的可能,所以还是查了下资料,主要是解释一些心里的疑惑。
疑问?
- java 能不能重载+、-、 =、==这些运算符
- java的Integer、Long这些类型的==运算符是比较地址还是使用
equals
的结果 - 为什么两个值为10的Integer对象,用==比较的结果是true,而两个值为1000的Integer对象的比较结果为false?
解答!
1. 能不能重载运算符?
不能。
有些人疑问,可是String对象可以有形如"hello worl" + 'd'
的操作,基本运算应该是不支持的。
这里是因为编译器在编译时处理成了Object s2 = (new StringBuilder("hello world")).append('d').toString();
的形式。
2. java的Integer、Long这些类型的==运算符是比较地址还是使用equals
的结果?
比较地址。
因为不能重载运算符,所以即便是这些特殊的类,依然只能在编译器上动动手脚。
3. 为什么两个值为10的Integer对象,用==比较的结果是true,而两个值为1000的Integer对象的比较结果为false?
Integer为-128~127范围内的对象做了缓存处理。
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
无论你是使用new Integer(..)还是Integer.valueOf(..)获取对象,
只要值在-128到127的范围内,拿到的就是缓存好的对象。因此无论是==运算符还是equals()方法,只要值相同,结果都是true。
而如果你的值在这个范围之外,==必然返回false,equals()方法的返回值依对象的值而定。
结论
无论如何,请使用equals()方法比较大小。