资讯专栏INFORMATION COLUMN

Java 性能要点:自动装箱/ 拆箱 (Autoboxing / Unboxing)

Jackwoo / 2489人阅读

摘要:文章主要介绍通过改进就已存在的骨灰级特性大幅度提高应用性能。在继续解释造成差异的细节之前,让我们仔细回味一下中的这两个概念自动装箱与拆箱。

【编者按】本文作者为 Ali Kemal TASCI,最早于2016年4月9日发布于DZONE社区。文章主要介绍通过改进 Java 1.5 就已存在的骨灰级特性大幅度提高应用性能。

本文系 OneAPM 工程师编译呈现,以下为正文。

如果我告诉你:“只要修改一个字符,下面这段代码的运行速度就能提高5倍。”,你觉得可能么?

long t = System.currentTimeMillis();
Long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms");

输出结果:
总数:2305843005992468481
处理时间:6756 ms

仔细琢磨一下,你可能会想到下面这种执行速度更快的实现方法:

long t = System.currentTimeMillis();//Long sum = 0L;long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum += i;
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms") ;

输出结果:
总数:2305843005992468481
处理时间:1248 ms

其实,自动装箱(Autoboxing)的草率使用是造成速度差异的根本原因,而这一特性从 Java 1.5 开始就已出现了。

在继续解释造成差异的细节之前,让我们仔细回味一下 Java 中的这两个概念:自动装箱(Autoboxing)与 拆箱(Unboxing)。

Java 中的变量分为两种:原始型与引用型。一共存在8个原始型变量以及与各个原始变量对应的8个引用变量(包装类)。

Primitive Types(原始型) Reference Types(Wrapper Class)(引用型,(包装类))
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double

下面的代码会介绍”Autoboxing“与”Unboxing“的用例。在这段代码中,一个类型为”long”的值被添加到类型为”Long“的List集合中。在 Java 1.4 中,为了实现此操作,我们必须将原始变量赋值到合适的引用类中(也即装箱,boxing)。从 Java 1.5 开始,编译器会帮我们完成这一操作。所以,我们不再需要写那么多代码。

List longList = new ArrayList<>();      
long i = 4;
longList.add( i ); //autoboxing      long j = longList.get( 0 ); //unboxing

从 Java 1.5 开始,编译器会自动将上面的代码段转化成如下代码:

List longList = new ArrayList<>();      
long i = 4;
longList.add(Long.valueOf( i ) );      
long j = longList.get( 0 ).longValue();

因此,我们也可以说,前文出现的第一段代码段会自动转化为如下代码。所以,导致处理时间较长的原因也就水落石出了:不必要地创建了2147483647个”Long“类型实例。

long t = System.currentTimeMillis();
Long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += new Long(i);
}
System.out.println("total:" + sum);
System.out.println("processing time: " + (System.currentTimeMillis() - t) + " ms") ;

由此可知,想要编写速度更快的 Java 代码,我们也需要考虑”Autoboxing”与”Unboxing”这样的基础概念。

相关资源集锦

Autoboxing and Unboxing
Autoboxing
Efective Java 2nd Edition, J. Bloch

OneAPM 为您提供端到端的 Java 应用性能解决方案,我们支持所有常见的 Java 框架及应用服务器,助您快速发现系统瓶颈,定位异常根本原因。分钟级部署,即刻体验,Java 监控从来没有如此简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客。

本文转自 OneAPM 官方博客

原文地址:https://dzone.com/articles/java-performance-notes-autoboxing-unboxing

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65808.html

相关文章

  • 深入浅出了解“装箱拆箱

    摘要:本章部分内容从源码中解读一些自动装箱与拆箱的原理,以及会出现的一些陷阱已经性能等。例题分析我们通过几个经典的问题,来看看大家到底理解了装箱与拆箱的知识点没。 showImg(https://img-blog.csdnimg.cn/20190426221838971.gif);showImg(https://img-blog.csdnimg.cn/20190426221918208.pn...

    FullStackDeveloper 评论0 收藏0
  • JAVA 三目运算时遇到的坑

    摘要:但是,三目运算符也是有一定的语言规范的。一三目运算符对于条件表达式,先计算条件,然后进行判断。那么,这段代码为什么会自动拆箱呢这其实是三目运算符的语法规范。所以,结果就是由于使用了三目运算符,并且第二第三位操作数分别是基本类型和对象。 三目运算符是我们经常在代码中使用的,a= (b==null?0:1);这样一行代码可以代替一个if-else,可以使代码变得清爽易读。 但是,三目运算符...

    jasperyang 评论0 收藏0
  • Java™ 教程(自动装箱拆箱

    自动装箱和拆箱 自动装箱是Java编译器在基元类型和相应的对象包装类之间进行的自动转换,例如,将int转换为Integer,将double转换为Double,依此类推,如果转换是另一种方式,则称为拆箱。 以下是自动装箱的最简单示例: Character ch = a; 本节中的其余示例使用泛型,如果您还不熟悉泛型的语法,请参阅泛型课程。 考虑以下代码: List li = new ArrayLis...

    cuieney 评论0 收藏0
  • Java Integer的缓存策略

    摘要:整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。这种缓存策略仅在自动装箱的时候有用,使用构造器创建的对象不能被缓存。行的结果为而行则为。所以行的结果为而行为。中其他类似的缓存的缓存上限可以通过虚拟机参数修改,的缓存则没法修改。 Java5为Integer的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。上面的规则默...

    endiat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<