对于自动装箱和拆箱,有一个大家熟知的程序。--摘自《Efficetive Java》
public static void main(String[] args) throws Exception {
long sum = 0L;
long start = System.currentTimeMillis();
for (long i = 1l; i <= Integer.MAX_VALUE; i ++) {
sum = sum + i;
}
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
执行耗时:1343ms
现在修改程序,将long sum = 0L;修改成Long sum = 0L;重新执行这段代码。
public static void main(String[] args) throws Exception {
Long sum = 0L;
long start = System.currentTimeMillis();
for (long i = 1l; i <= Integer.MAX_VALUE; i ++) {
sum = sum + i;
}
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
执行耗时:8484ms
可以发现,只修改了一个字符,但是时间消耗是原来6倍还要多。
那是为什么呢?是因为自动装箱,导致程序构造了差不多2^31个Long对象,所以慢。那么自动装箱又是怎么一回事呢?
按照个人理解,其实就是对于编译class文件时的一种处理。在编译期间,代码含义不变,但是对你本身的代码进行了优化,自动进行了基础类型和代码之间的转换。
那么可以对class文件进行反编译来查看一下,如下:
public static void main(String[] args) throws Exception {
Long sum = Long.valueOf(0L);
long start = System.currentTimeMillis();
for (long i = 1L; i <= 2147483647L; i += 1L) {
sum = Long.valueOf(sum.longValue() + i);
}
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
从这个class反编译可以看到,所谓的自动装箱、拆箱,
从最浅显的说法来说,就是优化了代码,类型转换自动帮你实现。
从上面的实验,可以从中衍生一些其他的东西出来
1.比如说两个不同基础类型的封装对象进行比较大小,其实比较的他们的基础类型(自动拆箱成为基础类型进行比较)
2.比如说两个不同基础类型的封装对象进行用==比较呢?当然,这个在用IDE的时候,会提示你有问题。就算是你强制进行编译,也会报错。
我用Long.valueOf(1) == Integer.valueOf(1)进行比较,IDE报错,强制编译->Error:(54, 29) java: 不可比较的类型: java.lang.Long和java.lang.Integer
所以使用==比较的时候,其实不是一个装箱拆箱的过程了,就是对象本身进行的比较。
可以参考:http://blog.csdn.net/qiuchengjia/article/details/52910915?locationNum=3&fps=1