基本介绍

2020 年 3 月 17 日,JDK / Java 14 正式 GA(General Available)。这是自从 Java 采用六个月一次的发布周期之后的第五次发布。

此版本包含的 JEP Java/JDK Enhancement Proposals JDK 增强提案)比 Java 12 和 13 加起来的还要多。总共 16 个新特性,包括两个孵化器模块 、三 个预览特性、两个弃用的功能以及两个删除的功能。

  • 「孵化器模块」:将 尚未定稿的 API 和工具先交给开发者使用,以获得反馈,并用这些反馈进一步改进 Java 平台的质量。
  • 「预览特性」:是规格已经成型、实现已经确定,但还未最终定稿的功能。它们出现在 Java 中的目的是收集在真实世界中使用后的反馈信息,促进这些功能的最终定稿 。这些特性可能会随时改变,根据反馈结果, 这些特性甚至可能会被移除,但通常所有预览特性最后都会在 Java 中固定下来。

环境准备

安装 JDK 14 https://www.oracle.com/technetwork/java/javase/overview/index.html

安装编译器:IDEA 2020.1 或者 Eclipse 2020-03

新特性介绍

JEP 305:instanceof 的模式匹配(预览特性)

这个特性很有意思,因为它为更为通用的模式匹配打开了大门。模式匹配通过更为简便的语法基于一定的条件来抽取对象的组件,而 instanceof 刚好是这种情况,它先检查对象类型,然后再调用对象的方法或访问对象的字段。

在 Java 14 之前,我们使用 instanceof 是这样的

@Test
public void test01() {
Object obj = "hello java14";
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str.contains("hello"));
} else {
System.out.println("不是 String 类型");
}
}

在 Java 14 中是这样的,相当于将上面的第4、5行代码简化了,省略了强制转化的过程,注意:「str 的作用域依旧是 if 结构内」

@Test
public void test02() {
Object obj = "hello java14";
if (obj instanceof String str) {
System.out.println(str.contains("hello"));
} else {
System.out.println("不是 String 类型");
}
}

有了该功能,可以减少 Java 程序中显式强制转换的数量,从而提高生产力,还能实现更精确、简洁的类型安全的代码 。

JEP 358:非常实用的 NullPointerException

该特性改进了 NullPointerException 的可读性,能更准确地给出 null 变量的信息 。

就是这个老爷子当年发明的 null,让成千上万的程序员深恶痛绝,他称自己犯了一个价值十亿美金的错误,那就是空指针!

《Java 8 实战》中是这样说的:

  • 它是错误之源。 NullPointerException 是目前 Java 程序开发中最典型的异常。它会使你的代码膨胀。
  • 它让你的代码充斥着深度嵌套的 null 检查,代码的可读性糟糕透顶。
  • 它自身是毫无意义的。 null 自身没有任何的语义, 尤其是 它代表的是在静态类型语言中以一种错误的方式对缺失变量值的建模。
  • 它破坏了 Java 的哲学。 Java 一直试图避免让程序员意识到指针的存在,唯一的例外是:null 指针。
  • 它在 Java 的类型系统上开了个口子。 null 并不属于任何类型,这意味着它可以被赋值给任意引用类型的变量。这会导致问题, 原因是当这个变量被传递到系统中的另一个部分后,你将无法获知这个 null 变量最初赋值到底是什么类型。

在 Java 8 中引入了 Optional,Optional 在可能为 null 的对象上做了一层封装,强制你思考值不存在的情况,这样

就能避免潜在的空指针异常 。

在 Java 14 中,对于 NPE 有了一个增强,该特性可以更好地提示哪个地方出现的空指针

需要我们在运行参数上加上 -XX:+ShowCodeDetailsInExceptionMessages 开启此功能,这个增强特性不仅适用于方法调用,只要会导致 NullPointerException 的地方也都适用,包括字段的访问、数组的访问和赋值 。

JEP 359:Record (预览特性)

我们有时候需要编写许多低价值的重复代码来实现一个简单的数据载体类:构造函数,访问器,equals()、hashCode()、toString() 等。为了避免这种重复代码,Java 14 推出了 record 。

该预览特性提供了一种更为紧凑的语法来声明类。 值得一提的是,该特性可以大幅减少定义类似数据类型时所需的样板代码。

使用 record 来减少类声明语法,效果类似 lombok 的 @Data 注解, Kotlin 中的 data class 。它们的共同点是类的部分或全部状态可以直接在类头中描述,并且这个类中只包含了纯数据而已。

我们声明一个 record 类型的类

public record Person(String name, Integer age) {
}

它编译后的 class 文件如下

public final class Person extends java.lang.Record {
private final java.lang.String name;
private final java.lang.Integer age; public Person(java.lang.String name, java.lang.Integer age) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public java.lang.String name() { /* compiled code */ } public java.lang.Integer age() { /* compiled code */ }
}

调用其属性的时候与普通类有所不同

@Test
public void test3(){
Person person = new Person("张三", 12);
person.name();
person.age();
}

当你用 record 声明一个类时,该类将自动拥有以下功能:

  • 获取成员变量的简单方法,以上面代码为例 name() 和 partner() 。注意区别于我们平常 getter 的写法。
  • 一个 equals 方法的实现,执行比较时会比较该类的所有成员属性
  • 重写 equals 当然要重写 hashCode
  • 一个可以打印该类所有成员属性的 toString 方法。
  • 请注意只会有一个构造方法。

和枚举类型一样,记录也是类的一种受限形式。 作为回报,记录对象在简洁性方面提供了显著的好处。

但是需要注意:

  • 可以在 Record 声明的类中定义静态字段、静态方法、构造器或实例方法。
  • 不能在 Record 声明的类中定义实例字段;类不能声明为 abstract;不能声明显式的父类等。

JEP 361:switch 表达式

这是 JDK 12 和 JDK 13 中的预览特性,现在是正式特性了。

我们使用 -> 来替代以前的 :break,另外还提供了 yield 来在 block 中返回值

代码演示:

public class SwitchExpression {
public static void main(String[] args) {
Season type = Season.AUTUMN;
String s = switch (type) {
case SPRING -> "春";
case SUMMER -> "夏";
case AUTUMN -> "秋";
case WINTER -> "冬";
default -> {
System.out.println("没有" + type + "这个选项");
yield "error";
}
};
}
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
}

JEP 368:文本块(预览第二版)

在 Java 中,通常需要使用 String 类型表达 HTML XML SQL 或 JSON 等格式的字符串,在进行字符串赋值时需要进行转义和连接操作,然后才能编译该代码,但这种表达方式难以阅读并且难以维护。

于是在 JDK13 中引入了 text blocks,JDK 14 进行了第二轮 preview,JDK14 的版本主要增加了两个功能,分别是\\s

例如我们要写一个 sql 语句,使用普通的字符串是这样的,这是比较简单的语句,如果复杂一点,简直不堪入目

@Test
public void test1() {
String sql =
"SELECT name, age\n" +
"FROM user\n" +
"WHERE age = 19";
System.out.println(sql);
}

使用了代码块是这样的,可读性变高了

@Test
public void test2(){
String sql = """
SELECT name, age
FROM user
WHERE age = 19
""";
System.out.println(sql);
}

但是运行上述代码可以看出,代码块里写的是什么格式就会输出什么格式,如果我们想让它只输出一行,可读性也高呢?

这时,我们可以使用 JDK 14 新加的 \(取消换行)和 \s(一个空格)

@Test
public void test3(){
String sql = """
SELECT name, age \
FROM user\s\
WHERE age = 19\s\
""";
System.out.println(sql);
}

JEP 366 :弃用 ParallelScavenge 和 SerialOld GC 组合

JDK 官方给出将这个 GC 组合标记为 Deprecate 的理由是:这个 GC 组合需要大量的代码维护工作,并且,这个 GC 组合很少被使用。因为它的使用场景应该是一个很大的 Young 区配合一个很小的 Old 区,这样的话, Old 区用 SerialOldGC 去收集时停顿时间我们才能勉强接受 。

废弃了 parallel young generation GC 与 SerialOld GC 的组合( XX:+UseParallelGC 与 XX: UseParallelOldGC 配合开启 ),现在使用 -XX:+UseParallelGC -XX:-UseParallelOldGC 或者 -XX:-UseParallelOldGC 都会出现如下警告:

Java HotSpot(TM) 64 Bit Server VM warning: Option UseParallelOldGC was deprecated in version 14.0 and will likely be removed in a future release.

JEP 363 :删除 CMS 垃圾回收器

该来的总会来,自从 G1 基于 Region 分代 )横空 出世后, CMS 在 JDK9 中就被标记为 Deprecate 了( JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector)

CMS 的弊端:

  1. 会产生内存碎片,导致并发清除后,用户线程可用的空间不足 。
  2. 既然强调了并发( Concurrent),CMS 收集器 对 CPU 资源非常敏感。
  3. CMS 收集器无法处理浮动垃圾

上述的这些问题,尤其是碎片化问题,给你的 JVM 实例就像埋了一颗炸弹。说不定哪次就在你的业务高峰期来一次 FGC。当 CMS 停止工作时,会把 Serial Old GC 作为备选方案,而 Serial Old GC 是 JVM 中性能最差的垃圾回收方式,停顿个几秒钟,上十秒都有可能 。

移除了 CMS 垃圾收集器,如果在 JDK14 中使用 XX:+UseConcMarkSweepGC 的话,JVM 不会报错,只是给出一个 warning 信息。

JEP:ZGC on macOS and windows

先看一下 ZGC 的恐怖性能,它可以在尽可能对吞吐量影响不大的前提下,实现在任意堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内的低延迟。

JEP 364:ZGC 应用在 macOS 上、JEP 365:ZGC 应用在 Windows 上

JDK14 之前, ZGC 仅 Linux 才支持 。尽管许多使用 ZGC 的用户都使用类 Linux 的环境,但在 Windows 和 macOS 上,人们也需要 ZGC 进行开发部署和测试。许多桌面应用也可以从 ZGC 中受益。因此, ZGC 特性被移植到了 Windows 和 macOS 上。

使用方式:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

虽然 ZGC 还在试验状态,没有完成所有特性,但此时性能已经相当亮眼,用「令人震惊、革命性」来形容,不为过。未来将在服务端、大内存、低延迟应用的首选垃圾收集器。


有几个不重要的新特性没有列举,可自行查看相关资料

本文大部分的资料来源于此视频的课件:https://www.bilibili.com/video/BV1tC4y147US

Java14:你需要知道的新特性的更多相关文章

  1. Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览

    当大潮退去,才知道谁在裸泳..关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis. ...

  2. 一文带你看遍 JDK9~14 的重要新特性!

    Java9 发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如 ...

  3. 从Java 9 到 Java 17 新特性梳理

    Java 9 新的创建集合的方法  // [1, 2, 3, 4]  List<Integer> integers = List.of(1, 2, 3, 4);  // {1,2,3}   ...

  4. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  5. ElasticSearch 5学习(10)——结构化查询(包括新特性)

    之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...

  6. [干货来袭]C#6.0新特性

    微软昨天发布了新的VS 2015 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下也是昨天发布的新的C#6.0的部分新特性吧.. ...

  7. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  8. 【译】Meteor 新手教程:在排行榜上添加新特性

    原文:http://danneu.com/posts/6-meteor-tutorial-for-fellow-noobs-adding-features-to-the-leaderboard-dem ...

  9. 跨平台的 .NET 运行环境 Mono 3.2 新特性

    Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...

随机推荐

  1. iOS 原生库(AVFoundation)实现二维码扫描,封装的工具类,不依赖第三方库,可高度自定义扫描动画及界面(Swift 4.0)

    Create QRScanner.swift file // // QRScanner.swift // NativeQR // // Created by Harvey on 2017/10/24. ...

  2. golang超级mapper包 - coven

    coven介绍 你可以把它理解成.NET 的 AutoMapper,java的modelmapper 一个快速的转换器去,支持结构到结构,切片到切片和映射到映射非反射转换,类型与嵌套指针支持. 不支持 ...

  3. pytorch tensor的索引与切片

    切片方式与numpy是类似. * a[:2, :1, :, :], * 可以用-1索引. * ::2,表示所有数据,间隔为2,即 start:end:step. *  a.index_select(1 ...

  4. HDU 1847-Good Luck in CET-4 Everybody!-博弈SG函数模板

    Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...

  5. 我们是怎么实现gRPC CodeFirst-生成proto

    前言: gRPC默认是ProtoFirst的,即先写 proto文件,再生成代码,需要人工维护proto,生成的代码也不友好,所以出现了gRPC CodeFirst,下面来说说我们是怎么实现gRPC ...

  6. 使用Docsify做文档网站的详细配置教程

    使用Docsify做文档网站的详细配置教程 作者:xhemj 没错,它叫Docsify. xhemj的文档中心就是用这个写的 开源地址:https://github.com/docsifyjs/doc ...

  7. 走近源码:Redis如何清除过期key

    "叮--",美好的周六就这么被一阵钉钉消息吵醒了. 业务组的同学告诉我说很多用户的帐号今天被强制下线.我们的帐号系统正常的逻辑是用户登录一次后,token的有效期可以维持一天的时间 ...

  8. FastText的内部机制

    文章来源:https://towardsdatascience.com/fasttext-under-the-hood-11efc57b2b3 译者 | Revolver fasttext是一个被用于 ...

  9. Linux常用命令 - find命令基础使用(重点)

    1篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 首先,先 ...

  10. 史上最详细的Docker安装手册

    概述: 这个安装手册我已经使用了将近2年的时间,一直在进行完善(可以用于生产级别).使用了Centos 7系统. 一.Docker简单介绍 Docker是一个容器,使用的是Linux现有的技术,准确来 ...