jdk 12 主要的新特性参考:
openjdk JDK 12
baeldung New Features in Java 12
JDK 12 的新特性
- 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
- 230: Microbenchmark Suite
- 325: Switch Expressions (Preview)
- 334: JVM Constants API
- 340: One AArch64 Port, Not Two
- 341: Default CDS Archives
- 344: Abortable Mixed Collections for G1
- 346: Promptly Return Unused Committed Memory from G1
语法变动
String 类的新增方法
Java 12 为String 类引入了两个新方法 indent 和 transform。
- indent
indent 更具其int 参数调节了String 每一行的缩进。参数n大于0,则String 每行增加n个空格,参数n小于0则String 删除每行前面的空格。
如果每行前面的空格数小于参数n,则删除所有空格(其他内容完好无损的保留下来)
1 | String text = "Hello Baeldung!\nThis is Java 12 article."; |
输出
1 | Hello Baeldung! |
即时参数是 -10 也只会删除前面4个空格。
- transform
transform只有一个参数Function,把自己通过 Function进行转换
1 | public <R> R transform(Function<? super String, ? extends R> f) { |
比如倒置一个String
1 |
|
File::mismatch 方法
Java 12 中在 nio.file.Files 工具类中新增了 mismatch 方法
1 | public static long mismatch(Path path, Path path2) throws IOException |
这个方法比较两个文件,并返回第一处内容不相等的字节位置(long)。 如果文件完全相等,返回-1L
看两个列子,第一个例子比较完全相同的两个文件,返回-1L
1 |
|
第二个例子,两个文件内容分别是 Java 12 Article 和 Java 12 Tutorial,应该返回8L表示第八个字节是不一样的(A and T)
1 |
|
Stream API 中的 Collectors.teeing()
Java 12中在 Collectors 类中新增了teeing 收集器:
1 | Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1, |
该收集器将其输入转发给其他两个收集器,然后将它们的结果使用函数合并。
下面例子使用利用 teeing处理一个数值 set, 第一个collector 求和,第二个collector 统计数值个数,最后通过 merger 合并结果计算平均值:
1 |
|
紧凑的数字格式
Java 12 新增了一个新的数字格式 —— 紧凑数字格式 。因为较大的数字总是难以识别具体数值,紧凑的表示更容易阅读且占据更少的展示空间。
我们可以通过 NumberFormat 类的 getCompactNumberInstance 方法获取其实例:
1 | public static NumberFormat getCompactNumberInstance(Locale locale, NumberFormat.Style formatStyle) |
通过参数 locale 提供了一个合适的格式,formatStyle可以是 SHORT or LONG ,比如 US locale 中数字 1000formatStyle是 SHORT则对应的就是 10K ,而 LONG 则是 10 thousand。
具体使用两个 formatStyle的代码例子:
1 |
|
预览版的特性
有一些特性是作为预览版本在 java 12 中发布的,如果要使用他们需要在编译的时候增加额外的配置
1 | javac -Xlint:preview --enable-preview -source 12 src/main/java/File.java |
Switch表达式 (Preview)
Java 12中引入的最有名的特性就是 Switch 表达式
我们用一个例子(LocalDate 实例的DayOfWeek 枚举判断是否是工作日)看下新老 switch 表达式的区别,Java 12 之前的版本:
1 | DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); |
同样的逻辑使用 switch 表达式
1 | typeOfDay = switch (dayOfWeek) { |
switch 表达式 更简洁易读,它取消了 break 语句,但不会再匹配后继续执行。另一个优势是现在可以把 switch表达式赋予一个变量, 这个在以前是不可能实现的。
同时,在switch 语句中可以直接代码且并不要求一定要有返回值:
1 | switch (dayOfWeek) { |
如果需要执行的逻辑比较复杂,可以使用 {}
1 | case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> { |
Java 12 中的switch 表达式只是一个可选的扩展语法,并不是说要直接代替了原来的 switch 。
switch Expressions 会在 Java 13 (转正了) 做更深入的说明。
instanceof 的匹配模式 (Preview)
另一个Preview 版本的特性就是 instanceof.
在之前的Java版本,当使用 instanceof 的时候通常都会需要额外写一个类型转化
1 | Object obj = "Hello World!"; |
java 12 中我们可以直接声明一个新的类型变量代表转化后的值
1 | if (obj instanceof String s) { |
编译器自动帮我们转换成了 String s 。
JVM 相关的变化
Java 12 中引入了一系列 JVM的增强特性,这里只挑选了几个比较重要的说明。
Shenandoah 垃圾回收器
Shenandoah 是一个低延迟的垃圾回收器。Java 12中 Shenandoah 还是实验性质的 (在Java 15 中会正式启用)。
Shenandoah 通过与Java线程同时执行清理工作来减少GC暂停时间。这意味着使用 Shenandoah,无论堆有多大,垃圾回收200 GB堆或2 GB堆停顿的时间都是固定的(垃圾收集器的停顿时间限制在10ms以内)。
ps. Shenandoah 收集器是由 RedHat 公司开发的项目,Oracle 拒绝在 OracleJDK12 中支持该收集器,Shenandoah 只有在 OpenJDK 中才会包含,而 OracleJDK 中不包含的。
Microbenchmark Suite
Java 12 introduces a suite of around 100 microbenchmark tests to the JDK source code.
These tests will allow for continuous performance testing on a JVM and will become useful for every developer wishing to work on the JVM itself or create a new microbenchmark.
Java 12 新增了大概100个 套微基准测试,提供给JVM性能测试用的。
Default CDS Archives
The Class Data Sharing (CDS) feature helps reduce the startup time and memory footprint between multiple Java Virtual Machines. It uses a built-time generated default class list that contains the selected core library classes.
The change that came with Java 12 is that the CDS archive is enabled by default. To run programs with CDS turned off we need to set the Xshare flag to off:
1 | java -Xshare:off HelloWorld.java |
Note, that this could delay the startup time of the program.
就是 CDS 在Java 12 中默认就是开启的,需要通过 -Xshare:off 关闭(启动会变慢), CDS 的内容在 Java 10 新特性中提到过。
总结
就写这么多吧, 关于 G1 垃圾回收器还是以后单独写一篇吧。