点击上方"IT牧场",选择"设为星标"

技术干货每日送达!

Java 14 GA(General Availability) 版本已经于3月17日发布。

Java 14 包含的 JEP(Java Enhancement Proposals 的缩写,Java 增强建议)比 Java 12 和 13 两个版本加起来还要多。那么,对于每天编写和维护代码的 Java 开发人员来说,哪个特性值得我们关注呢?

本文我将介绍以下几个重要功能:

•改进的 switch 表达式,最初作为预览在 Java 12 和 Java 13 中出现,现在完全成为 Java 14 的一部分。•instanceof 模式匹配(Pattern matchin),这是一个语言特性;•非常有用的 NullPointerExceptions,是 JVM 的一个特性。

如果你阅读了本文并在你的代码库中尝试了其中的一些特性,你可以通过向 Java 团队提供反馈来分享你的经验。通过这样做,您就有机会为 Java 的开发做出贡献。好了,咱们废话不多说,现在来详细看看 Java 14 值得每一个 Java 关注的新特性。

Switch 表达式(Switch Expressions)

在 Java 14 中,switch 表达式正式成为语言的一部分。如果你不知道 switch 表达式是什么,可以看下这几篇文章 New switch Expressions in Java 12[1]、《Inside Java 13’s switch Expressions and Reimplemented Socket API》[2]、以及 《JDK 13 都已经来了!五大新特性你最喜欢哪个 ?》。

在以前 Java 12 和 Java 13 的版本中,switch 表达式是一个“预览”特性。这里注意,被指定为“预览”的特性主要用以收集反馈,并可能根据反馈进行更改甚至删除;不过其中的大多数最终将成为 Java 一部分。

新的 switch 表达式的好处包括减少了 bug 的范围,而且得助于表达式和复合形式,使 switch 的编写变得简单。比如 switch 表达式现在可以利用箭头语法:

var log = switch (event) {case PLAY -> "User has triggered the play button";case STOP, PAUSE -> "User needs a break";default -> {String message = event.toString();LocalDateTime now = LocalDateTime.now();yield "Unknown event " + message + " logged on " + now;}
};

文本块(Text Blocks)

Java 13 首次引入了文本块,并且作为预览特性。文本块使处理多行字符串更容易。在 Java 14 中,这个特性仍然是预览特性,并做了一些调整。在之前,为了提供足够的多行文本格式,使用许多字符串连接和转义序列来编写代码是很常见的。比如下面的代码展示了一个 HTML 格式化的例子:

String html = "<HTML>" +
"\n\t" + "<BODY>" +
"\n\t\t" + "<H1>\"Java 14 is here!\"</H1>" +
"\n\t" + "</BODY>" +
"\n" + "</HTML>";

有了文本块之后,你可以简化这个过程,并使用分隔文本块开头和结尾的三个引号编写更优雅的代码:

String html = """
<HTML><BODY><H1>"Java 14 is here!"</H1></BODY>
</HTML>""";

与普通字符串文字相比,文本块还提供了更强的表达能力。你可以阅读这篇文章:《Text Blocks Come to Java》。

在 Java 14 中添加了两个新的转义字符。首先,可以使用新的 \s 转义字符表示单个空格。其次,可以使用反斜杠 \来禁止在行的末尾插入新行字符。当你想要在文本块中分割一个很长的行以提高可读性时,这是很有帮助的。

比如,当前处理多行字符串的方法如下:

String literal = "Lorem ipsum dolor sit amet, consectetur adipiscing " +"elit, sed do eiusmod tempor incididunt ut labore " +"et dolore magna aliqua.";

有了 \ 转义字符之后,我们可以在文本块中这么来写:

String text = """Lorem ipsum dolor sit amet, consectetur adipiscing \elit, sed do eiusmod tempor incididunt ut labore \et dolore magna aliqua.\""";

instanceof 的模式匹配

Java 14 引入了一个预览特性,该特性有助于消除在执行 instanceof 检查之后,还需要显式强制转换的需要。例如,考虑以下代码:

if (obj instanceof Group) {Group group = (Group) obj;// use group specific methodsvar entries = group.getEntries();
}

可以使用这个新功能,将上面代码重构如下:

if (obj instanceof Group group) {var entries = group.getEntries();
}

因为条件检查已经判断出 obj 是 Group 类型的,那么为什么还需要在代码中显示转换 obj 为 Group 类型呢?而且这可能会增加错误的范围。

新的语法将从典型的 Java 程序中删除许多类型转换。(2011年的一份研究报告显示,大约24%的 cast 都是在进行 instanceof 判断之后进行的。)

JEP 305 涵盖了这一变化,并指出了来自 Joshua Bloch 的《Effective Java book》中的一个示例,该示例如下:

@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString) && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}

通过删除对 CaseInsensitiveString 的显式强制转换,可以将前面的代码简化为以下形式:

@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString cis) &&cis.s.equalsIgnoreCase(s);
}

这是一个值得体验的有趣特性,因为它为更通用的模式匹配打开了大门。模式匹配的思想是为基于一定条件提取对象的组件提供一种语法方便的语言特征。instanceof 操作符就是这种情况,因为条件是类型检查,提取过程调用适当的方法或访问特定的字段。

换句话说,这个预览特性只是一个开始,我们可以期待一个能够帮助进一步减少冗余代码的语言特性,从而减少 bug 的可能性。

Records

另一个值得关注的预览语言特性:records。与目前提出的其他特性一样,该特性遵循了减少 Java 语言冗长的趋势,并帮助开发人员编写更简洁的代码。Recods 关注特定的域类(domain classes ),这些域类的目的只是在字段中存储数据,并且不声明任何自定义行为。

为了说明这个特性,假设我们有一个域类 BankTransaction,它用三个字段构建一个事务:日期、金额和描述。由于我们需要考虑和其他组件进行交互,所以我们还需要以下一些方法:

•构造器•Getter 方法•toString() 方法•hashCode() 和 equals() 方法 这些代码通常由 IDE 自动生成,占用大量空间。下面是完整生成的 BankTransaction 类实现:

public class BankTransaction {private final LocalDate date;private final double amount;private final String description;public BankTransaction(final LocalDate date, final double amount, final String description) {this.date = date;this.amount = amount;this.description = description;}public LocalDate date() {return date;}public double amount() {return amount;}public String description() {return description;}@Overridepublic String toString() {return "BankTransaction{" +"date=" + date +", amount=" + amount +", description='" + description + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;BankTransaction that = (BankTransaction) o;return Double.compare(that.amount, amount) == 0 &&date.equals(that.date) &&description.equals(that.description);}@Overridepublic int hashCode() {return Objects.hash(date, amount, description);}
}

Java 14 提供了一种方法来删除这些代码,并明确表示您想要的只是一个类,它只将数据与 equals、hashCode 和 toString 方法的实现聚合在一起。您可以重构 BankTransaction 如下:

public record BankTransaction(LocalDate date,double amount,String description) {}

使用 record 来标记我们的类,我们的类将自动获取 equals、hashCode 和 toString 方法,除此之外,类的构造函数和 getters 方法也将自动得到。

如果你想要尝试这个功能,在编译这个类的时候你需要加上预览标记:

javac --enable-preview --release 14 BankTransaction.java

record 标记的类中 Fields 将隐式设置成 final,也就意味着我们不能修改它。但是需要注意的是,这并不意味着 recod 标记的类是不可修改的(immutable)。存储在字段中的对象本身可以是可变的。

有用的 NullPointerExceptions

有些人说,抛出 NullPointerExceptions 应该成为 Java 中新的“Hello world”,因为我们无法摆脱它们。撇开玩笑不谈,当代码在生产环境中运行时,NullPointerExceptions 经常出现在应用程序日志中,这可能会使调试变得困难,因为原始代码并不容易获得。例如,考虑下面的代码:

var name = user.getLocation().getCity().getName();

在 Java 14 之前,你可能得到以下的错误:

Exception in thread "main" java.lang.NullPointerExceptionat NullPointerExample.main(NullPointerExample.java:5)

不幸的是,在第5行代码中,有多个方法调用的赋值——getLocation() 和 getCity()——其中任何一个都可能返回 null。实际上,变量 user 也可以是 null。所以,目前还不清楚是什么导致了 NullPointerException。

不过在 Java 14,新的 JVM 特性将给我们提供更多有用的信息:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Location.getCity()" because the return value of "User.getLocation()" is nullat NullPointerExample.main(NullPointerExample.java:5)

上面的异常信息包含两个方面的信息:

•结果:Location.getCity() 无法被调用;•原因:User.getLocation() 的返回值是 null。要使用这个功能,需要在 JVM 中加入以下标记

-XX:+ShowCodeDetailsInExceptionMessages

以下是一个示例:

java -XX:+ShowCodeDetailsInExceptionMessages NullPointerExample

根据 JDK-8233014,在未来的 Java 版本,这个特性可能会默认启用。

这种增强不仅可用于方法调用,还可用于其他可能导致 NullPointerException 的地方,包括字段访问、数组访问和赋值等。

好了今天的分享就到这里了。

本文翻译自:Java 14 Arrives with a Host of New Features[3]

引用链接

[1] New switch Expressions in Java 12: https://blogs.oracle.com/javamagazine/new-switch-expressions-in-java-12
[2] 《Inside Java 13’s switch Expressions and Reimplemented Socket API》: https://blogs.oracle.com/javamagazine/inside-java-13s-switch-expressions-and-reimplemented-socket-api
[3] Java 14 Arrives with a Host of New Features: https://blogs.oracle.com/javamagazine/java-14-arrives-with-a-host-of-new-features

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术讨论群

近期热文

•彻底解决 GitHub 拉取代码网速慢的问题•基于 SpringBoot2 和 Netty 实现一个简易的RPC通信框架•一本彻底搞懂MySQL索引优化EXPLAIN百科全书•盘点 10 个代码重构的小技巧•性能测试如何定位瓶颈?偶发超时?看高手如何快速排查问题•震精!Spring Boot内存泄露,排查竟这么难!


想知道更多?长按/扫码关注我吧↓↓↓>>>技术讨论群<<<喜欢就点个"在看"呗^_^

Java 14 GA 版本正式发布相关推荐

  1. Kong 1.0 GA 版本正式发布,微服务 API 网关

    Kong 1.0 GA 版本已正式发布,这是一款可扩展.快速且开源的微服务 API 网关,用于管理.保护与连接混合及云原生架构.Kong 运行于全部服务之前,并可以通过插件实现各种扩展,例如身份验证. ...

  2. Apache Hadoop 3.0.0 GA版正式发布,可以部署到线上

    今天凌晨 Apache Hadoop 3.0.0 GA 版本正式发布,这意味着我们就可以正式在线上使用 Hadoop 3.0.0 了!这个版本是 Apache Hadoop 3.0.0 的第一个稳定版 ...

  3. 七、Java 14 新特性

    七.Java 14 新特性 Java 14 已如期于 2020 年 3 月 17 日正式发布,此次更新是继半年前 Java 13 这大版本发布之后的又一次常规版本更新,即便在全球疫情如此严峻形势下,依 ...

  4. JDK/Java 14 正式发布!然而我还在用 Java 8...

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | oschina 来源 | https://ww ...

  5. 甲骨文正式发布Java 14(Oracle JDK 14)

    甲骨文两年来,每六个月如约发布新版本的Java,Oracle JDK 14为开发人员带来创新功能和新特性预览.Oracle JDK 14增加了一些新特性来提高开发人员工作效率,这些新特性包括:对swi ...

  6. Java 7~14各个版本新特性详解

    Java 7 特性列表 switch中添加对String类型的支持 数字字面量的改进 / 数值可加下划 异常处理(捕获多个异常) try-with-resources 增强泛型推断 JSR203 NI ...

  7. 如今甲骨文正式发布Java 14……

    甲骨文两年来,每六个月如约发布新版本的Java,Oracle JDK 14为开发人员带来创新功能和新特性预览.Oracle JDK 14增加了一些新特性来提高开发人员工作效率,这些新特性包括:对swi ...

  8. Java 14:JDK 14进入GA时的所有新功能

    是的,六个月过去了这么快,现在到了,Java 14的发布即将到来. 我们一直在跟踪新JDK在过去半年中的进展,您可以在此处找到摘要的所有功能. 但是,如果您想直接进入,可以在此处找到JDK 14二进制 ...

  9. 甲骨文正式发布Java 14(Oracle JDK 14),下载下来尝尝鲜~~~

    Java一直以来都是深受软件开发者青睐的首选编程语言.伴随着Java 14创新功能的按时交付,对未来的周详规划以及对生态系统的持续投入,Java平台将继续为现代应用开发注入动力. 代码示例: publ ...

最新文章

  1. 使用模块化编译缩小 apk 体积
  2. 查出引起死锁的进程和SQL语句
  3. 网站SEO优化中几个不为人知的小细节分享!
  4. LeetCode-Sort List 链表排序
  5. 学习Git_12.10
  6. make的自动变量和预定义变量
  7. Iterator(迭代器)--对象行为模式
  8. 最近用.NET实现DHT爬虫,全.NET实现
  9. zookeeper 可视化_大厂,常用,四款,大屏可视化工具
  10. Listview 的应用 Day04 2014-0605
  11. sketch 将动图转换为json_UI设计师如何创建sketch设计样式、库和UI套件
  12. Jquery+CSS Input file 文本框轻美化
  13. 15.go install
  14. 402.移掉K位数字
  15. 信息化、数字化、智能化到底有什么区别
  16. IntelliJ IDEA运行内存设置
  17. 【正点原子MP157连载】第二章 Ubuntu系统入门-摘自【正点原子】【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
  18. 使用ONVIF Device Test Tool获取网络摄像头的音/视频
  19. 用Python快速制作海报级地图!
  20. 北大郭炜《程序设计与算法(三)》Mooc笔记:运算符重载和继承

热门文章

  1. 个人代码库の迅雷7动态图标按钮模拟
  2. JAVA Collections类
  3. [论文笔记]Episodic Curiosity through Reachability
  4. java面试之常见场景题
  5. QTranslate国际化及多语言切换
  6. Native English
  7. Oracle创建新用户
  8. Java --- 堆空间大小设置与OutOfMemoryError(OOM)
  9. winform实现FTP上传、下载、删除文件(附源码下载)
  10. 使用StopWatch计算耗时