JDK 9-13都更新了什么

都9102年了,你在使用JDK哪个版本呢?在今年 InfoQ 的 2019 中国 Java 发展趋势报告 中,Java 8 已经列入了晚期大众的行列。所以,今天就带大家一起梳理一下 Java 最近都更新了什么?

https://static001.geekbang.org/wechat/images/83/838fc3a4b6394b9ca226caaa4b8ed199.jpeg

自从2017年后,JDK就疯狂刷版本号,大家之呼:“别更新了,学不动了”。2017年 Oracle 确认 Java 的发布频率改为每六个月一次。之前的 Java 发布周期为每两年一次,但是,常常因为一些特性未完成等,一直延期,例如 JDK 8 延期了 8 个月,JDK 9 延期了 18 个月。为了避免不断的延期,故修改更新策略,新版本的发布不会等到某个主要的特性完成,而是将该特性并入到下一个版本,并且严格按照时间点就行版本发布,每年的 3 月和 9 月就是新版本的发布月。

同时Oracle提供了长期支持版本 LTS, JDK 8 就是一个LTS版本,支持日期到2025年。而继 JDK 8 之后,JDK 11 为下一个LTS,支持日期到2026年。

下面总结一些 JDK 更新的重要特性,毕竟每次更新的东西太多了。

JDK 9 是 JDK 8 时隔 三年半之后才发布的新版本,因为模块特性而一再延期。

这是 JDK 9 中的一个重要特性,通过module我们可以指定 jar 包中那些类是可以被访问的,那些类是不可以被外部访问的。同时减少了 Jar 包打包的大小。即使是 public 也不意味着可以被外部包所访问。

module 通过在 src 下的 module-info.java 进行定义。

例如 定义了 student 和 teacher 两个模块。如果我需要在 main 模块中使用这两个模块,首先要在 main 引入所需要的 module。

1
2
3
4
module main {
    requires teacher;
    requires student;
}

之后要在 student 和 teacher 模块中导出我们需要的 package。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// student module

module student {
    exports top.young.student;
}

// teacher module 
module teacher {
    requires student;
    exports top.young.teacher;
}

这样才完成了一次 module 之间的调用。

同时 JDK 也被拆分成了 94 个模块,通过 jlink 工具,创建出包含依赖的 JDK 自定义的运行时镜像,极大的减少了 Java 的 runtime 的大小。

Jshell 的添加可是 Javaer 的福音,实现一个小的想法再也不需要写一坨无关的代码了。Jshell 是一个 REPL 工具,即 读取(R) 执行(E) 输出(P) 再循环(L)。Jshell 启动也是非常方便的,只要在终端输入 jshell 即可打开。

https://island-hexo.oss-cn-beijing.aliyuncs.com/jshel.png

JDK 8 的时候添加了 Stream 流进行操作,而 JDK 9 的时候又添了4个函数。这 4 个函数分别为 dropWhiletakeWhile 、``ofNullableiterate`。

dropWhile 是读取流中的元素,当满足条件是将元素丢弃,不满足条件时结束。

1
2
3
4
5
public class Main {
    public static void main(String[] args) {
        Stream.of(6,4,7,9,2,1).dropWhile(it -> it >= 3).forEach(System.out::println); // 2 1
    }
}

同样 takeWhile 是从流中读取元素,满足条件时获取,不满足条件结束。

1
2
3
4
5
public class Main {
    public static void main(String[] args) {
        Stream.of(6,4,7,9,2,1).takeWhile(it -> it >= 3).forEach(System.out::println); // 6 4 7 9
    }
}

对 Null 流元素进行过滤,防止发生 NPE

1
2
3
4
5
public class Main {
    public static void main(String[] args) {
      Stream.of(6, 4, null, 9, 2, 1).flatMap(Stream::ofNullable).forEach(System.out::println);//6 4 9 2 1
    }
}

该方法对指定初始种子进行创建,每次按照 next 的规则进行更改,直到条件满足 hasNext。

1
2
3
4
5
public class Main {
    public static void main(String[] args) {
        Stream.iterate(3, x -> x < 10, x -> x + 3).forEach(System.out::println);// 3 6 9
    }
}

说起响应式编程大家一定不陌生,毕竟之前有 Rx 系列一直在做,而 JDK 9 加入了 java.util.concurrent.Flow

Flow 包含了4个核心接口: Flow.PublisherFlow.SubscriberFlow.SubscriptionFlow.Processor

更多的 JDK 9 更新内容可以查看 JDK9 官方更新日志

JDK 10 是

终于可以用 var 来做类型推断了,注意 var 并不是关键字,而是保留的类型名称。比如我们这样写也是对的 var var = 6;

但是 var 声明类型只在以下情况中使用:

  • 声明的同时赋值
  • 再 for 循环中。

改善了 java.util.Locale类和相关API以外的实现。尤其是对货币类型,一周第一天等信息的支持。

G1 垃圾回收器是 Java 9 中 Hotspot 默认的垃圾回收器,为了最大限度地减少 Full GC 造成的应用停顿响应,所以 Java 10 为 G1 引入了多线程并行 GC。

jdk 11 是目前的最新的 lts。也是大部分公司即 JDK1.8 之后开始使用的另一个 JDK 版本。JDK 11 语法上没有较大的新特性变化。主要变化在安全特性和性能更新。

在 JDK 9 提出后,JDK 10 更新,JDK 11 标准化。