天天说装箱基本类型,那。。。
在Java的类型系统中,有两部分:primitive(基本类型)、reference type(引用类型)。每一个基本类型都有一个其对应的引用类型,称为「装箱基本类型」。
| 基本类型 | 装箱基本类型 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
装箱基本类型用着很爽?但是有时候使用不当会引发一些bug哦~~~
有时候,我们会用到比较器,比较Integer的值。猜猜下面这段代码的结果是多少?
public static void main(String[] args) throws InterruptedException {
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer first, Integer second) {
return first < second ? -1 : (first == second ? 0 : 1);
}
};
Integer first = new Integer(42);
Integer second = new Integer(42);
int compare = comparator.compare(first, second);
System.out.println(compare);
}
答案:「1」。
疑惑吗?别着急,再来一个,下面这段代码结果是啥?
public class TestInteger {
static Integer i;
public static void main(String[] args) {
if (i == 42) {
System.out.println(true);
}
}
}
答案:NullPointerException
哈哈哈哈~~~
小老弟,脑瓜子是不是嗡嗡的,想不想静静~~~
好了,开始正题。
基本类型和装箱基本类型有着三点不同:
基本类型只有值,装箱基本类型有两个属性:值和同一性(我们经常说的内存地址)。
基本类型只有值,装箱基本类型有值或者
null。基本类型比装箱基本类型更节省时间和空间。
这里面啊,还有个-128 ~ 127的问题。这个后面再说。
对于第一题,在first<second这个好理解。
「运算符==用在基本类型(int)的比较上,比较的是基本类型的值。但是,如果用在装箱基本类型上(Integer),比较的是两者的内存地址」,first 和 second 两个变量都是new Integer()出来的,内存地址不同。所以,这个==返回的是false,现在知道最后的答案为什么是1了吧?
这里我们可以用三点不同里的第一条解释。对于第一题,可以将first和second拆箱再来比较。
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer first, Integer second) {
int f = first;
int s = second;
return f < s ? -1 : (f == s ? 0 : 1);
}
};
来吧,第二题!
在==操作中,「如果有基本类型和装箱基本类型混合操作时,装箱基本类型会自主拆箱」,所以,当我们的装箱基本类型是null时,拿一个空值去拆箱,结果可想而知啊!
接下来还有一个小题目,看看这段代码有没有什么问题。
public class TestLong {
public static void main(String[] args) {
Long sum = 0L;
long s1 = System.currentTimeMillis();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(System.currentTimeMillis() - s1);
}
}
结果:不会bug,但是运行速度比较慢。
原因:sum这个变量被定义成装箱基本类型,在for循环中sum不断的被装箱拆箱,导致性能明显的下降。
各位看官可以试试将sum定义成long,然后再试试这段代码的性能。
public class TestLong {
public static void main(String[] args) {
long sum = 0;
long s2 = System.currentTimeMillis();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(System.currentTimeMillis() - s2);
}
}
经过小助手运行之后,结果相差非常大:
装箱基本类型耗时 : 7044
基本类型耗时 : 644
是不是很吃惊???
最后给大家留了个小思考题,很简单。
public static void main(String[] args) {
Integer s1 = 127, s2 = 127, t1 = 128, t2 = 128;
System.out.println(s1 == s2);
System.out.println(t1 == t2);
Integer s3 = new Integer(127);
Integer s4 = new Integer(127);
Integer t3 = new Integer(128);
Integer t4 = new Integer(128);
System.out.println(s3 == s4);
System.out.println(t3 == t4);
}
提示:-128 ~ 127,又发现新知识点了吧!
推荐阅读
「长按识别下方二维码」,关注「摸鱼小助手」,回复「Python书籍」,免费书籍就到手了哦!
作者个人微信二维码,来交个朋友吧!
希望在学习的路上,小助手可以助您一臂之力,一路顺风哦~~~~