写点什么

这次没跳票!Java 10 正式发布,带来了这些新特性

  • 2018-03-22
  • 本文字数:5089 字

    阅读完需:约 17 分钟

看新闻很累?看技术新闻更累?试试下载 InfoQ 手机客户端,每天上下班路上听新闻,有趣还有料!

北京时间 3 月 21 日,Oracle 官方宣布 Java 10 正式发布。这是 Java 大版本周期变化后的第一个正式发布版本(详见这里),非常值得关注。你可以点击以下地址即刻下载:

http://www.oracle.com/technetwork/java/javase/downloads/index.html

去年 9 月,Oracle 将 Java 大版本周期从原来的 2-3 年,调整成每半年发布一个大的版本。而版本号仍延续原来的序号,即 Java 8、Java 9、Java 10、Java 11…

但和之前不一样的是,同时还有一个版本号来表示发布的时间和是否为 LTS(长期支持版本),比如 Java 10 对应 18.3。如下示例:

复制代码
/jdk-10/bin$ ./java -version
openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+46)
OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

需要注意的是 Java 9 和 Java 10 都不是 LTS 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本(得到 Oracle 等商业公司的长期支持服务)。

这种发布模式已经得到了广泛应用,一个成功的例子就是 Ubuntu Linux 操作系统,在偶数年 4 月的发行版本为 LTS,会有很长时间的支持。如 2014 年 4 月份发布的 14.04 LTS,Canonical 公司和社区支持到 2019 年。类似的,Node.js,Linux kernel,Firefox 也采用类似的发布方式。

Java 未来的发布周期,将每半年发布一个大版本,每个季度发布一个中间特性版本。这样可以把一些关键特性尽早合并入 JDK 之中,快速得到开发者反馈,可以在一定程度上避免 Java 9 两次被迫推迟发布日期的尴尬。

下图为 2017 年 JavaOne 大会时,Oracle 公开的未来 Java 版本发布和支持周期图。

Java 10 新特性

这次发布的 Java 10,新带来的特性并不多。

根据官网公开资料,共有 12 个 JEP(JDK Enhancement Proposal 特性加强提议),带来以下加强功能:

  1. JEP286,var 局部变量类型推断。
  2. JEP296,将原来用 Mercurial 管理的众多 JDK 仓库代码,合并到一个仓库中,简化开发和管理过程。
  3. JEP304,统一的垃圾回收接口。
  4. JEP307,G1 垃圾回收器的并行完整垃圾回收,实现并行性来改善最坏情况下的延迟。
  5. JEP310,应用程序类数据 (AppCDS) 共享,通过跨进程共享通用类元数据来减少内存占用空间,和减少启动时间。
  6. JEP312,ThreadLocal 握手交互。在不进入到全局 JVM 安全点 (Safepoint) 的情况下,对线程执行回调。优化可以只停止单个线程,而不是停全部线程或一个都不停。
  7. JEP313,移除 JDK 中附带的 javah 工具。可以使用 javac -h 代替。
  8. JEP314,使用附加的 Unicode 语言标记扩展。
  9. JEP317,能将堆内存占用分配给用户指定的备用内存设备。
  10. JEP317,使用 Graal 基于 Java 的编译器,可以预先把 Java 代码编译成本地代码来提升效能。
  11. JEP318,在 OpenJDK 中提供一组默认的根证书颁发机构证书。开源目前 Oracle 提供的的 Java SE 的根证书,这样 OpenJDK 对开发人员使用起来更方便。
  12. JEP322,基于时间定义的发布版本,即上述提到的发布周期。版本号为\$FEATURE.\$INTERIM.\$UPDATE.\$PATCH,分别是大版本,中间版本,升级包和补丁版本。

部分特性说明

1. var 类型推断。

这个语言功能在其他一些语言 (C#、JavaScript) 和基于 JRE 的一些语言 (Scala 和 Kotlin) 中,早已被加入。

在 Java 语言很早就在考虑,早在 2016 年正式提交了 JEP286 提议。后来举行了一次公开的开发者调查,获得最多建议的是采用类似 Scala 的方案,“同时使用 val 和 var”,约占一半;第二多的是“只使用 var”,约占四分之一。后来 Oracle 公司经过慎重考虑,采用了只使用 var 关键字的方案。

有了这个功能,开发者在写这样的代码时:

ArrayList<String> myList = new ArrayList<String>()可以省去前面的类型声明,而只需要

var list = new ArrayList<String>()编译器会自动推断出 list 变量的类型。对于链式表达式来说,也会很方便:

复制代码
var stream = blocks.stream();
...
int maxWeight = stream.filter(b -> b.getColor() == BLUE)                      .mapToInt(Block::getWeight)                      .max();

开发者无须声明并且 import 引入 Stream 类型,只用 stream 作为中间变量,用 var 关键字使得开发效率提升。

不过 var 的使用有众多限制,包括不能用于推断方法参数类型,只能用于局部变量,如方法块中,而不能用于类变量的声明,等等。

另外,我个人认为,对于开发者而言,变量类型明显的声明会提供更加全面的程序语言信息,对于理解并维护代码有很大的帮助。一旦 var 被广泛运用,开发者阅读三方代码而没有 IDE 的支持下,会对程序的流程执行理解造成一定的障碍。所以我建议尽量写清楚变量类型,程序的易读维护性有时更重要一些。

2. 统一的 GC 接口

在 JDK10 的代码中,路径为 openjdk/src/hotspot/share/gc/,各个 GC 实现共享依赖 shared 代码,GC 包括目前默认的 G1,也有经典的 Serial、Parallel、CMS 等 GC 实现。

3. 应用程序类数据(AppCDS)共享

CDS 特性在原来的 bootstrap 类基础之上,扩展加入了应用类的 CDS(Application Class-Data Sharing) 支持。

其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时直接读取此启动文本并加载。设想如果应用环境没有大的变化,启动速度就会得到提升。

我们可以想像为类似于操作系统的休眠过程,合上电脑时把当前应用环境写入磁盘,再次使用时就可以快速恢复环境。

我在自己 PC 电脑上做以下应用启动实验。

首先部署 wildfly 12 应用服务器,采用 JDK10 预览版作为 Java 环境。另外需要用到一个工具 cl4cds[1],作用是把加载类的日志记录,转换为 AppCDS 可以识别的格式。

A、安装好 wildfly 并部署一个应用,具有 Angularjs, rest, jpa 完整应用技术栈,预热后启动三次,并记录完成部署时间

分别为 6716ms, 6702ms, 6613ms,平均时间为 6677ms。

B、加入环境变量并启动,导出启动类日志

export PREPEND_JAVA_OPTS="-Xlog:class+load=debug:file=/tmp/wildfly.classtrace"C、使用 cl4cds 工具,生成 AppCDS 可以识别的 cls 格式

/jdk-10/bin/java -cp src/classes/ io.simonis.cl4cds /tmp/wildfly.classtrace /tmp/wildfly.cls打开文件可以看到内容为:

复制代码
java/lang/Object id: 0x0000000100000eb0
java/io/Serializable id: 0x0000000100001090
java/lang/Comparable id: 0x0000000100001268
java/lang/CharSequence id: 0x0000000100001440
......
org/hibernate/type/AssociationType id: 0x0000000100c61208 super: 0x0000000100000eb0 interfaces: 0x0000000100a00d10 source: /home/shihang/work/jboss/wildfly/dist/target/wildfly-12.0.0.Final/modules/system/layers/base/org/hibernate/main/hibernate-core-5.1.10.Final.jar
org/hibernate/type/AbstractType id: 0x0000000100c613e0 super: 0x0000000100000eb0 interfaces: 0x0000000100a00d10 source: /home/shihang/work/jboss/wildfly/dist/target/wildfly-12.0.0.Final/modules/system/layers/base/org/hibernate/main/hibernate-core-5.1.10.Final.jar
org/hibernate/type/AnyType id: 0x0000000100c61820 super: 0x0000000100c613e0 interfaces: 0x0000000100c61030 0x0000000100c61208 source: /home/shihang/work/jboss/wildfly/dist/target/wildfly-12.0.0.Final/modules/system/layers/base/org/hibernate/main/hibernate-core-5.1.10.Final.jar
....

这个文件用于标记类的加载信息。

D、使用环境变量启动 wildfly,模拟启动过程并导出 jsa 文件,就是记录了启动时类的信息。

export PREPEND_JAVA_OPTS="-Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=/tmp/wildfly.cls -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=/tmp/wildfly.jsa"查看产生的文件信息,jsa 文件有较大的体积。

复制代码
/opt/work/cl4cds$ ls -l /tmp/wildfly.*
-rw-rw-r-- 1 shihang shihang   8413843 Mar 20 11:07 /tmp/wildfly.classtrace
-rw-rw-r-- 1 shihang shihang   4132654 Mar 20 11:11 /tmp/wildfly.cls
-r--r--r-- 1 shihang shihang 177659904 Mar 20 11:13 /tmp/wildfly.jsa

E、使用 jsa 文件启动应用服务器

export PREPEND_JAVA_OPTS="-Xshare:on -XX:+UseAppCDS -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=/tmp/wildfly.jsa"启动完毕后记录时长,三次分别是 5535ms, 5333ms, 5225ms,平均为 5364ms,相比之前的 6677ms 可以算出启动时间提升了 20% 左右。

这个效率提升,对于云端应用部署很有价值。

以上实验方法参考于技术博客 [2]。

4. JEP314,使用附加的 Unicode 语言标记扩展。

JDK10 对于 Unicode BCP 47 有了更多的支持,BCP 47 是 IETF 定义语言集的规范文档。使用扩展标记,可以更方便的获得所需要的语言地域环境。

如 JDK10 加入的一个方法,

java.time.format.DateTimeFormatter::localizedBy通过这个方法,可以采用某种数字样式,区域定义或者时区来获得时间信息所需的语言地域本地环境信息。

附:从链接 [3] 可以看到 JDK10 所有的方法级别改动。

5. 查看当前 JDK 管理根证书。

自 JDK9 起在 keytool 中加入参数 -cacerts,可以查看当前 JDK 管理的根证书。而 OpenJDK9 中 cacerts 为空,这样就会给开发者带来很多不变。

EP318 就是利用 Oracle 开源出 Oracle JavaSE 中的 cacerts 信息,在 OpenJDK 中提供一组默认的根证书颁发机构证书,目前有 80 条记录。

复制代码
/jdk-10/bin$ ./keytool -list -cacerts
Enter keystore password:   Keystore type: JKS
Keystore provider: SUN
Your keystore contains 80 entries
verisignclass2g2ca [jdk], Dec 2, 2017, trustedCertEntry,
Certificate fingerprint (SHA-256): 3A:43:E2:20:FE:7F:3E:A9:65:3D:1E:21:74:2E:AC:2B:75:C2:0F:D8:98:03:05:BC:50:2C:AF:8C:2D:9B:41:A1
......

下一版本展望

下一个 Java 大版本会是 Java 11,也是 Java 8 之后的 LTS 版本,预计会在今年的 9 月份发布。目前只有四个 JEP,更多加强提议会逐步加入。

这个版本会充分发挥模块化的能力,把当前 JDK 中的关于 JavaEE 和 Corba 的部分移除,变得更加紧凑。

虽然 JDK9 最大的亮点是模块化,但 Java 业界广泛接纳并且适应需要一个过程。当前已经有一些支持模块化的类库,如 log4j2,但大多数还未支持。

可以预见 JDK11 发布之后,模块化特性就成为长期支持特性,会有越来越多的类库提供对模块化的支持。

Java 依然会是最适合应用开发的语言和平台,庞大的社区和广泛的开发者,会不断促使 Java 不断完善优化,在各个编程领域继续发扬光大。

对文中引用文章原作者表示致谢!引用的图示,数据和方法都属于原作者。下一个 Java 大版本会是 Java 11,也是 Java 8 之后的 LTS 版本,预计会在今年的 9 月份发布。目前只有四个 JEP,更多加强提议会逐步加入。 这个版本会充分发挥模块化的能力,把当前 JDK 中的关于 JavaEE 和 Corba 的部分移除,变得更加紧凑。 虽然 JDK9 最大的亮点是模块化,但 Java 业界广泛接纳并且适应需要一个过程。当前已经有一些支持模块化的类库,如 log4j2,但大多数还未支持。 可以预见 JDK11 发布之后,模块化特性就成为长期支持特性,会有越来越多的类库提供对模块化的支持。 Java 依然会是最适合应用开发的语言和平台,庞大的社区和广泛的开发者,会不断促使 Java 不断完善优化,在各个编程领域继续发扬光大。 对文中引用文章原作者表示致谢!引用的图示,数据和方法都属于原作者。

[1]: https://simonis.github.io/cl4cds/

[2]: https://marschall.github.io/2018/02/18/wildfly-appcds.html

[3]: https://gunnarmorling.github.io/jdk-api-diff/jdk9-jdk10-api-diff.html#java.time.format.DateTimeFormatter

作者介绍

张建锋,永源中间件共同创始人,原红帽公司 JBoss 应用服务器核心开发组成员。毕业于北京邮电大学和清华大学,曾供职于金山软件,IONA 科技公司和红帽软件。

对于 JavaEE 的各项规范比较熟悉;开源技术爱好者,喜欢接触各类开源项目,学习优秀之处并加以借鉴,认为阅读好的源码就和阅读一本好书一样让人感到愉悦;在分布式计算,企业应用设计,移动行业应用,DevOps 等技术领域有丰富的实战经验和自己的见解;愿意思考软件背后蕴涵的管理思想,认为软件技术是一种高效管理的实现方式,有志于将管理学和软件开发进行结合。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2018-03-22 19:0010967

评论

发布
暂无评论
发现更多内容

程序员成长第二篇:如何快速入门

石云升

程序员 28天写作 2月春节不断更

你需要的Docker知识点都在这里了。

后台技术汇

28天写作 2月春节不断更

智汇华云 | ArSDN之多集群简介

华云数据

华云数据

GitHub 标星 167k!你要的优质书籍这都有,还开源!

沉默王二

GitHub 开源 电子书

【经验分享】如何融合CMMI与企业需求,自定义推进数字化转型

嘉为蓝鲸

DevOps 敏捷 持续交付 CMMI 能力成熟度模型

webpack | 进阶用法4:如何进行构建速度和体积分析

梁龙先森

大前端 webpack 28天写作 2月春节不断更

【CSS】css控制鼠标点击事件(pointer-events)

德育处主任

html/css CSS小技巧 28天写作 纯CSS 2月春节不断更

从JNOS商业操作系统,看京东零售商业化之路新探索

京东科技开发者

零售 数字化转型

【LeetCode】双指针反转字符串

Albert

算法 LeetCode 2月春节不断更

怎么和小伙伴语音连麦,你造吗?

anyRTC开发者

ios android WebRTC sdk 语音通话

工业互联网的“第一高地”,在哪?

工业互联网

考前复习必备MySQL数据库(关系型数据库管理系统)

我是哪吒

MySQL 程序员 面试 后端 2月春节不断更

熬夜肝了个IDEA插件整合程序员常用的工具,总有你能用上的

Silently9527

程序员 IDEA idea插件

超好用的文件转换神器!拿走不谢~

白色蜗牛

程序员 软件工具 生产工具

数据中心网络技术新贵:VXLAN与园区网络虚拟化

华为云开发者联盟

网络 数据中心 虚拟化 VXLAN 二层网络

最最新版钱包tok量化区块链挖矿系统源码

luluhulian

京东扫描平台EOS—JS扫描落地与实践

京东科技开发者

大前端

浅谈OKR工作法

一笑

管理 OKR 28天写作

手机里什么APP都没有,一个很无趣的人 | 视频号28天(27)

赵新龙

28天写作

并发队列:ArrayBlockingQueue实际运用场景和原理

叫练

阻塞队列 LinkedBlockingQueue 并发队列 阻塞List ArrayBlockingQueue

腾讯基于 Flink SQL 的功能扩展与深度优化实践

Apache Flink

flink

如果创意也可以被设计「幻想短篇 26/28」

道伟

28天写作

深入理解 ProtoBuf 原理与工程实践(概述)

vivo互联网技术

数据结构 序列化 protobuf

浏览器同源策略,听说过么?

华为云开发者联盟

浏览器 jsonp CORS 同源策略 跨域

Elasticsearch Document 查询内部原理

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

KubeEdge@MEC:Kubernetes容器生态与5G的结合

华为云开发者联盟

5G 边缘计算 网络 kubeedge 5G MEC

盘点软件开发中那些有趣的边际效应

架构精进之路

认知提升 七日更 28天写作 2月春节不断更

漫话递归与迭代

Justin

算法 方法论 成长 心灵鸡汤 28天写作

区块链矿机挖矿游戏开发,区块链矿机游戏开发

v16629866266

2天完成17TB数据量迁移,华为云数据库是如何做的?

华为云开发者联盟

数据库 mongodb 大数据 智慧地图 地理信息服务

火出圈的Clubhouse,究竟有什么奥秘?

拍乐云Pano

flutter RTC 语音聊天室 社交APP出海 clubhouse

这次没跳票!Java 10正式发布,带来了这些新特性_语言 & 开发_张建锋_InfoQ精选文章