前言
今天要说的易错点是关于java的8种基本类型的使用,很多初学者比较容易犯的错误,亦或是基础不牢者也常常会犯,下面我们一起看一下,先从一个例子说起。
例子1
public class BugTest2 {
public static void main(String[] args) {
Integer a = 10;
Integer b = 10;
Integer c = 150;
Integer d = 150;
System.out.println(a == b);
System.out.println(c == d);
}
}
结果:
true
false
分析:
🙄,怎么肥事???竟然一个是ture一个是false!!!我想基础比较好的同学可能立马能想到原因了,没错,就是你想的哪个。
出现这个结果的原因是:Byte、Short、Integer、Long、Char这几个装箱类的valueOf()方法是以128位分界线做了缓存的。
源码:
这里以Integer为例,其他的类似。
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们可以看到注释种这段话,This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range,意思就是说这个方法会缓存-128到127的整数。看到这里我想大多数人应该都能明白为什么会出现true和fasle的原因了。
例子2
public class BugTest3 {
public static void main(String[] args) {
Double d1 = 10.0;
Double d2 = 10.0;
Double d3 = 150.0;
Double d4 = 150.0;
System.out.println(d1 == d2);
System.out.println(d3 == d4);
}
}
结果:
fasle
fasle
分析:
额额额,为啥这次全是false了???一脸懵逼!原因其实很简单,8种基本类型种,整型是放在缓存的,但是浮点型的就不是了,浮点型位数并不像整型那么确定,无法有效的缓存起来。
源码:
/**
* Returns a {@code Double} instance representing the specified
* {@code double} value.
* If a new {@code Double} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Double(double)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param d a double value.
* @return a {@code Double} instance representing {@code d}.
* @since 1.5
*/
public static Double valueOf(double d) {
return new Double(d);
}
从源码种我们可以看到,是new了一个包装类出来,而不是从什么缓存种获取的。Folat也是类似,同理。
温馨提示:
如果我们想比较两个数值是不是相等,尽力不要用“==”去比较而是用包装类的equals()方法去比较,这样可以避免出错。