该如何从 Java 8 升级到 Java 10

Java 9 出来了很久,买的书《Java 9 Revealed - For Earyly Adoption and Migration》,说怎么迁移到 Java 9,可是突然间 Java 9 就无法通过正常渠道从 Oracle 官网下载了,这书还让不让人看。当然要看,因为尽管 Java 10 出来了,但实际的变化全压在 Java 9 这个版本上的,就当是通过 Java 10 来学习 Java 9 吧。

本文随便说说 Java 8 之后的版本变迁,不涉及 Java 9 或是 Java 10 的具体新特性,并不能回答标题中的问题。作为一个不甘落后的 IT 从业人员,总是希望能紧跟技术(某一狭小特定领域的技术)的步伐。譬如说当从 Java 1.4 升级到 Java 1.5 之后,对范型也是跃跃欲试,无奈当时公司追求的是稳定压倒一切,不在服务器上升级 JDK,所以只能创造条件也要上。于是弄了个 Retrotranslator让你用JDK1.5的特性写出的代码能在JVM1.4中运行 来适配。

后来的公司,也就是现在更为激进一些,来了 JDK 6,跟; JDK 7,跟; JDK 8, 继续跟; JDK 9 发布后,不跟了。不是不想跟,而是 Java 9 实在是变化有点大,模块化带来的不仅仅语言方面的改变,而是影响到如何组织,发布应用,这也就是为什么 jigsaw 雪藏多年的缘故。其实也可以对模块化不欲理会,但是单纯的把 Java 8 换成 Java 9 造成原来的项目不能正常构建的概率也比以往要高。

Java 8 是 2014 年 3 月发布,四后半后的 Java 9 在 2017 年 9 月发布,然而 2018 年 3 月 Java 10 就出来了。谁说 Oracle 在收购 Java 后就对它不作为了呢?Oracle 在 Java 9 之后开始了 6 个月的发布周期(见 Oracle Java SE Support Roadmap),这让人如何受得了,Oracle 自己也是。更何况我们都没来得急品尝 Java 9 的滋味,Oracle 自己就把 Java 9 的生命周期给结束了,进到 Java 9 的下载而面 Java SE 9 Downloads, 自动会导向到 Java SE 10 的下载页面,想要下载 Java SE 9 的话,只能到历史存档中去找 Java SE 9 Archive Downloads

Oracle 自然意识到从 Java 8 更上一层楼需要一个漫长的过程,所以它把对 Java 8 的支持延长到了 2025 年 3 月(中国制造?)。用不上 Java 9 是不是该直接跳到 Java 10 去,恐怕我们还是赶不上,因为 Java 10 也不是一个长期支持版(LTS),即将于 2018 年 9 月出品的 Java 11 才会是一个 LTS 版,它预计支持到 2026 年 9 月,命并不比 Java 8 长多少。

限制我们从 Java 8 往前进的还有一个很大的因素是目前各类云平台的跟进也缓慢,例如 AWS 的 Lambda 仍然只支持到 Java 8,如果是 ECS 上运行的服务我们是可以自己控制的。

如果在 Java 8 原地踏步时间太久了,离现实世界将会渐行渐远。目前只能稍稍对 Java 9 和 Java 10 的一些新特性保持稍微的敏感度,届时有可能直接从 Java 8 一个大跨步到 Java 11 或更高的版本,真要小心蛋了。下面是 Java 8 后两个版本主要的新特性

Java 9: 模块化(最难啃的),jlink(创建自定义镜像),JShell(产品中也用不着),改进的 Javadoc(也不是我主要关心的),集合工厂方法,改进的 Stream API,接口中可有私有方法,HTTP/2,统一的日志,多版本兼容的 Jar 包,等等

Java 10: 能感知到的新特性也就只有一个 var 对局部变量进行类型推断,这是我一直向往着的特性,因为 Scala 中一直这么用, C# 中也早就有了

相信 Java 11 中也不会带来太显著的特性,基本上是停留下来消化 Java 9 引进来的新特性。从此看来,似乎阻碍 Java 8 向新版本升级的最大障碍就是模块化了。

因为 Java 9 的离世,所以为了体验 Java 9 带来的新特性,我们可以直接安装 Java 10。固执一点的话也可以从故纸堆中翻出 Java 9 来体验它的原滋原味,我还真就打算这么做。本文不讲具体的新特性,只从大处着眼看 Java 9 较之以前的不同之处。

首先是安装 JDK 后的目录文件的变化,以 Linux 版本的 Java 8 与 Java 9 为例,其他平台应该类似

以前的 db 和 jre  目录不见了,而新增了 jmods 目录,并且 src.zip 和  javafx-src.zip 源文件也没带。目录名也跟以往不一样的,以前的称乎 JDK 5, 6, 7, 8 版本,同时又扭扭捏捏的分别叫做 1.5, 1.6, 1.7, 1.8 这样的版本号。现在干脆了,从目录名 jdk1.8.9_172 和 jdk-9.0.4 就能看出,现在不一样的,看下它们的 -version

看到它们的版本号分别是 1.8.0_172 和 9.0.4, 从此开启版本帝模式。就是从源代码中也不是 @since 1.7 的字样的,而是 @since 9。至于 JDK 版本的开发代码自 Java 8 就不再用了,从 JDK 1 的  Oak 到 Java 7 Dolphin 最后一个代号。

而且 Java 9 的 lib 中的内容远比 Java 8 的 lib 目录丰富

再就是 Java 9 后独有的 jmods 目录

可见 Java 9 的模块要求的对目录中每一个模块的精细划分,jlink 或 jimage 才得经从中拣出需要的模块构建自己的 Java 运行镜像,想像一下一个服务端程序为何带着 AWT, SWING, JavaFX 等包呢?当然 headless 的程序除外。

也有必要瞧瞧 /bin 目录中的不同

Java9 新增的命令有 jlink, jimage, jhsdb, jshell, jmod, jdeprscan, jaotc, jweblauncher。 但去除了 native2ascii 命令,在 UTF-8 几乎一统江湖的情况下真是用不着。

字节码中的主版本号严格的往上递增在 class 文件的第6, 7 字节

  • Java SE 10 = 54 (0x36)
  • Java SE 9 = 53 (0x35)
  • Java SE 8 = 52 (0x34)
  • Java SE 7 = 51 (0x33)
  • Java SE 6 = 50 (0x32)
  • Java SE 5 = 49 (0x31)
  • JDK 1.4 = 48 (0x30)
  • JDK 1.3 = 47 (0x2F)
  • JDK 1.2 = 46 (0x2E)
  • JDK 1.1 = 45 (0x2D)

在 IntelliJ IDEA 中导入 Java 8 和 Java 9 后显示的不同

引入的 Java 8 SDK, 显示的是一个个的 jar 包。是 Java 8 SDK 的 jre/lib 和 jre/lib/ext 下的所有 jar 包。

而 IntelliJ IDEA 中使用 Java 9 SDK 后,显示的是一个一个的模块,对应于 Java 9 SDK 的 jmod 目录中的所有 *.jmod 文件。

接下应该要进一步了解其他的一些 Java 9 新特性,很难从模块化先下嘴,会先从语法层面开始。

本文链接 https://yanbin.blog/how-to-upgrade-from-java-8-to-10/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

4 Comments
Inline Feedbacks
View all comments
Dobe
Dobe
5 years ago

反正还用着java6+7+8的我……。突然想起来微软也是从win8飞到了win10

wayne
wayne
5 years ago

按这个情况来看,岂不是用jdk1.8还是比较稳定的,综合感觉起来9到11都像是试验过度新功能都版本,没准到12出来到时候才是新功能大行其道到时代啊

wayne
wayne
5 years ago
Reply to  Yanbin

了解了,现在个大公司来说,为了稳定必然不会换jdk版本,固定在1.8了。
到时候11出来到时候,虽说是稳定输出版,但是改动太大,要全部重构又不见得会全部切换,还有一个是11只比8多维护1年。
估计趋势来看,1.8可能近几年还是会一枝独秀啊