JDK17 你的下一个白月光

JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。

但实际情况却不是这样,越来越多的java工程师拥抱 JDK17,于是了解了一下 JDK17新语法,感觉确实香啊,推荐大家一起试一下!

  • 长期支持版本
    JDK17是Oracle于2021年9月14日发布的一个长期支持版本(LTS)。它将获得长期的更新和支持,帮助保持程序的稳定性和可靠性。

  • 性能提升
    经过综合评估,我们发现在从Java 8升级到Java 11后,G1GC的平均速度提升了16.1%,ParallelGC则提升了4.5%。当从Java 11升级到Java 17时,G1GC的平均速度提升了8.66%,而ParallelGC则提升了6.54%。这些结果是基于对OptaPlanner用例的基准测试得出的。总的来说,这些优
    化让垃圾回收器更加优秀。
    最大的亮点是带来了稳定版的ZGC垃圾回收器,达到亚毫秒级停顿。

  • 新语法和特性
    Switch表达式简化、Text Blocks文本块、instanceof的模式匹配升级和NullPointerException提示信息改进等
    支持最新的技术和框架
    Spring framework6 和Spring Boot3 都默认使用 Java 17作为最低版本

  • 压测结果
    JDK17相对于JDK8和JDK11,所有垃圾回收器的性能都有很明显的提升,特别是稳定版的ZGC垃圾回收器。不论任何机器配置下,都推荐使用ZGC,ZGC的停顿时间达到亚毫秒级,吞吐量也比较高

一、JDK17 新语法

1. 文本块

推荐指数:⭐️⭐️⭐️⭐️⭐️

这个更新非常实用。在没有这个特性之前,编写长文本非常痛苦,充满拼接符号。现在,通过字符串块,我们可以轻松编写JSON、HTML、SQL等内容,效果更清爽。

原来的写法

/*** 使用JDK8返回HTML文本** @return 返回HTML文本*/
public static final String getHtmlJDK8() {return "<html>\n" +" <body>\n" +" <p>Hello, world</p>\n" +" </body>\n" +"</html>";
}

新的写法

/*** 使用JDK17返回HTML文本** @return 返回HTML文本*/
public static final String getHtmlJDK17() {return """<html><body><p>Hello, world</p></body></html>""";
}

2. NullPointerException增强

推荐指数:⭐️⭐️⭐️⭐️⭐️

这一功能非常强大且实用,相信每位Java开发者都期待已久。空指针异常(NPE)一直是Java程序员的痛点,因为报错信息无法直观地指出哪个对象为空,只抛出一个NullPointerException和一堆堆栈信息,定位问题耗时且麻烦。
Java17终于在这方面取得了突破,提供了更详细的空指针异常信息,帮助开发者迅速定位问题源头。

public static void main(String[] args) {try {//简单的空指针String str = null;str.length();} catch (Exception e) {e.printStackTrace();}try {//复杂一点的空指针var arr = List.of(null);String str = (String)arr.get(0);str.length();} catch (Exception e) {e.printStackTrace();}
}

运行结果

3. Records

推荐指数:⭐️⭐️⭐️⭐️

在Java中,POJO对象(如DO、PO、VO、DTO等)通常包含成员变量及相应的Getter和Setter方法。尽管可以通过工具或IDE生成这些代码,但修改和维护仍然麻烦。
Lombok插件为此出现,能够在编译期间自动生成Getter、Setter、hashcode、equals和构造函数等代码,使用起来方便,但对团队有依赖要求。
为此,Java引入了标准解决方案:Records。它通过 简洁的语法定义数据类,大大简化了POJO类的编写,如下所示。虽然hashcode和equals方法仍需手动编写,但IDE能够自动生成。这一特性有效解决了模板代码问题,提升了代码整洁度和可维护性。

package com.summo.jdk17;/**** @param stuId     学生ID* @param stuName   学生名称* @param stuAge    学生年龄* @param stuGender 学生性别* @param stuEmail  学生邮箱*/
public record StudentRecord(Long stuId,String stuName,int stuAge,String stuGender,String stuEmail) {public StudentRecord {System.out.println("构造函数");}public static void main(String[] args) {StudentRecord record = new StudentRecord(1L, "张三", 16, "男", "xxx@qq.com");System.out.println(record);}
}

4. 全新的switch表达式

推荐指数:⭐️⭐️⭐️

在Java12的时候就引入了switch表达式,注意这里是表达式,而不是语句,原来的switch是语句。
如果不清楚两者的区别的话,最好先去了解一下。主要的差别就是就是表达式有返回值,而语句则没有。
配合 模式匹配,以及yield和“->”符号的加入,全新的switch用起来爽到飞起来。

package com.summo.jdk17;public class SwitchDemo {/*** 在JDK8中获取switch返回值方式** @param week* @return*/public int getByJDK8(Week week) {int i = 0;switch (week) {case MONDAY, TUESDAY:i = 1;break;case WEDNESDAY:i = 3;break;case THURSDAY:i = 4;break;case FRIDAY:i = 5;break;case SATURDAY:i = 6;break;case SUNDAY:i = 7;break;default:i = 0;break;}return i;}/*** 在JDK17中获取switch返回值** @param week* @return*/public int getByJDK17(Week week) {// 1, 现在的switch变成了表达式,可以返回值了,而且支持yield和->符号来返回值// 2, 再也不用担心漏写了break,而导致出问题了// 3, case后面支持写多个条件return switch (week) {case null -> -1;case MONDAY -> 1;case TUESDAY -> 2;case WEDNESDAY -> 3;case THURSDAY -> {yield 4;}case FRIDAY -> 5;case SATURDAY, SUNDAY -> 6;default -> 0;};}private enum Week {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY}
}

5. 私有接口方法

推荐指数:⭐️⭐️⭐️

从Java8开始,允许在interface里面添加 默认方法,但有一个问题,如果一个default方法体很大怎么办,拆到另外的类去写吗?实在有些不太合理,
所以在Java17里面,如果一个default方法体很大,那么可以通过新增接口私有方法来进行一个合理的拆分了。

public interface PrivateInterfaceMethod {/*** 接口默认方法*/default void defaultMethod() {privateMethod();}// 接口私有方法,在Java8里面是不被允许的,不信你试试private void privateMethod() {}
}

6. 模式匹配

推荐指数:⭐️⭐️⭐️⭐️

在JDK 17中,模式匹配 主要用于 instanceof 表达式。
模式匹配 增强了instanceof的语法和功能,使 类型检查 和 类型转换 更加简洁和高效。
在传统的Java版本中,我们通常使用 instanceof 结合 类型转换 来 判断对象类型 并 进行处理,这往往会导致冗长的代码。

原来的写法

/*** 旧式写法** @param value*/
public void matchByJDK8(Object value) {if (value instanceof String) {String v = (String)value;System.out.println("遇到一个String类型" + v.toUpperCase());} else if (value instanceof Integer) {Integer v = (Integer)value;System.out.println("遇到一个整型类型" + v.longValue());}
}

新的写法

/*** 转换并申请了一个新的变量,极大地方便了代码的编写** @param value*/
public void matchByJDK17(Object value) {if (value instanceof String v) {System.out.println("遇到一个String类型" + v.toUpperCase());} else if (value instanceof Integer v) {System.out.println("遇到一个整型类型" + v.longValue());}
}

7. 集合类的工厂方法

推荐指数:⭐️⭐️⭐️⭐️⭐️

在Java8的年代,即便创建一个很小的集合,或者 固定元素 的集合都是比较麻烦的。

原来的写法

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c"

新的写法

Set<String> set = Set.of("a", "b", "c");

二、其他的新特性

1. 新的String方法

  • repeat:重复生成字符串
  • isBlank:不用在引入第三方库就可以实现字符串判空了
  • strip:去除字符串两边的空格,支持全角和半角,之前的trim只支持半角
  • lines:能根据一段字符串中的终止符提取出行为单位的流
  • indent:给字符串做缩进,接受一个int型的输入
  • transform:接受一个转换函数,实现字符串的转换

2. Stream API的增强

增加takeWhile, dropWhile, ofNullable, iterate以及toList的API,越来越像一些函数式语言了。用法举例如下。

// takeWhile 顺序返回符合条件的值,直到条件不符合时即终止继续判断,
// 此外toList方法的加入,也大大减少了节省了代码量,免去了调用collect(Collectors::toList)方法了
List<Integer> list = Stream.of(2,2,3,4,5,6,7,8,9,10).takeWhile(i->(i%2==0)).toList(); // 返回2, 2// dropWhile 顺序去掉符合条件的值,直到条件不符合时即终止继续判断
List<Integer> list1 = Stream.of(2,2,3,4,5,6,7,8,9,10).dropWhile(i->(i%2==0)).toList(); //返回3, 4, 5, 6, 7, 8, 9, 10// ofNullable,支持传入空流,若没有这个且传入一个空流,那么将会抛NPE
var nullStreamCount = Stream.ofNullable(null).count(); //返回0// 以下两行都将输出0到9
Stream.iterate(0, n -> n < 10, n -> n + 1).forEach(x -> System.out.println(x));
Stream.iterate(0, n -> n + 1).limit(10).forEach(x -> System.out.println(x));

3. 全新的HttpClient

这个API首次出现在9之中,不过当时并非是一个稳定版本,
在Java11中正式得到发布,所以在Java17里面可以放心地进行使用。
原来的JDK自带的Http客户端真的非常难用,这也就给了很多像okhttp、restTemplate、Apache的HttpClient和feign这样的第三方库极大的发挥空间,几乎就没有人愿意去用原生的Http客户端的。
但现在不一样了,感觉像是 新时代的API了。FluentAPI风格,处处充满了现代风格,用起来也非常地方便,再也不用去依赖第三方的包了,好用。

// 同步请求
HttpClient client = HttpClient.newBuilder().version(Version.HTTP_1_1).followRedirects(Redirect.NORMAL).connectTimeout(Duration.ofSeconds(20)).proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))).authenticator(Authenticator.getDefault()).build();HttpResponse<String> response = client.send(request, BodyHandlers.ofString());System.out.println(response.statusCode());System.out.println(response.body()); // 异步请求
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://foo.com/")).timeout(Duration.ofMinutes(2)).header("Content-Type", "application/json").POST(BodyPublishers.ofFile(Paths.get("file.json"))).build();client.sendAsync(request, BodyHandlers.ofString()).thenApply(HttpResponse::body).thenAccept(System.out::println);

4. JShell

在新的JDK版本中,支持直接在命令行下执行java程序,类似于python的交互式REPL。
简而言之,使用 JShell,你可以输入代码片段并马上看到运行结果,然后就可以根据需要作出调整,这样在验证一些简单的代码的时候,就可以通过jshell得到快速地验证,非常方便。

5. java命令 直接执行 java文件

在现在可以直接通过执行“java xxx.java”,即可运行该java文件,无须先执行javac,然后再执行java,是不是又简单了一步。

6. ZGC

在ParallelOldGC、CMS和G1之后,JDK 11引入了全新的ZGC(Z Garbage Collector)。这个名字本身就显得很牛。官方宣称ZGC的 垃圾回收 停顿时间不超过10ms,能支持高达16TB的堆空间,并且停顿时间不会随着堆的增大而增加。
.
那么,ZGC到底解决了什么问题?
Oracle官方介绍它是一个可伸缩的低延迟垃圾回收器,旨在降低停顿时间,尽管这可能会导致吞吐量的降低。
不过,通过横向扩展服务器可以解决吞吐量问题。官方已建议ZGC可用于生产环境,这无疑将成为未来的主流垃圾回收器。

小结:
随着Java8即将停止免费官方支持,越来越多的项目将转向Java17,包括大名鼎鼎的Spring Boot 3.0,它在2022年1月20日发布的第一个里程碑版本(M1)正是基于Java17构建的。
大多数情况下,从 JDK 8 升级到 JDK 17 是可行的,但需要对应用程序进行适当的测试和调整,以确保其在新版本上的稳定运行。
但是如果项目中其他成员使用了某些新特性,在Java8下将无法通过编译.,到时候再换就有点晚了

三、各版本 收费情况

JDK4 系列

Java 4.2.30 以后的所有版本

JDK5系列

Java 5.0.22 以后的所有版本

JDK6系列

Java 6.0.45以后的所有版本

JDK7系列

Java 7.0.80以后的所有版本

JDK8系列

Java 8.0.202以后的所有版本

JDK11~16系列

Java 11~16的所有版本

JDK17系列

Java 17 – 2024年12月以后所发布的所有版本

JDK21系列

预计到2027年JDK21也开始收费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/27551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Star-CCM+自动网格执行方法与设置技巧

在Star中进行一个仿真项目时,有时会创建多个自动网格。网格创建结束后需要执行。在Star中,网格执行可以分为三种。分别是:单独执行操作;多个执行操作;全部执行操作。接下来将三种执行操作的方法与步骤进行介绍。 其次,如果不习惯用自定义控制网格,有时在一个项目中就会…

大模型+人工智能:重塑地方志管理的新力量

前言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度渗透到各个领域&#xff0c;改变着我们的工作和生活方式。特别是在地方志管理这一领域&#xff0c;大模型和人工智能的结合正在开启一场深刻的变革。今天&#xff0c;就让我们一起…

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】梯度的反向传播算法

矩阵微积分&#xff08;Matrix Calculus&#xff09; 在开始之前&#xff0c;需要先了解矩阵微积分的一些计算规则。 首先&#xff0c;对于矩阵微积分的表示&#xff0c;通常由两种符号约定&#xff1a; 分母布局 标量关于向量的导数为列向量 向量关于标量的导数为行向量 N维…

LDR6500:手机电脑拓展坞转接器方案的卓越之选

随着科技的飞速发展&#xff0c;手机和电脑已成为我们日常生活中不可或缺的工具。然而&#xff0c;它们的接口有限&#xff0c;经常难以满足我们多样化的需求。这时&#xff0c;一款高效、稳定的拓展坞转接器就显得尤为重要。LDR6500&#xff0c;作为乐得瑞科技精心研发的USB P…

【计算机视觉(10)】

基于Python的OpenCV基础入门——图像滤波去噪 图像滤波去噪均值滤波中值滤波高斯滤波双边滤波方框滤波图像滤波去噪代码实现及其效果图 图像滤波去噪 图像滤波去噪是一种图像处理方法&#xff0c;它通过应用滤波器来减少或消除图像中的噪声。噪声是图像中不希望的、无用的、干…

安装sqlserver2022 express

1、下载 SQL Server 下载 | Microsoft 双击sql2022-ssei-expr 2、安装 下载完成以后&#xff0c;将会出现以下对话框 &#xff1a; 点击【全新SQL Server独立安装或向现有安全添加功能】 下一步&#xff0c;下一步&#xff1a; 下一步&#xff1a; 下一步&#xff0c;这里我…

【LeetCode:2779. 数组的最大美丽值 + 排序 + 二分】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【docker】如何解决artalk的跨域访问问题

今天折腾halo的时候&#xff0c;发现artalk出现跨域访问报错&#xff0c;内容如下。 Access to fetch at https://artk.musnow.top/api/stat from origin https://halo.musnow.top has been blocked by CORS policy: The Access-Control-Allow-Origin header contains multipl…

Kotlin编程实践-【Java如何调用Kotlin中带默认值参数的函数】

问题 如果你有一个带有默认参数值的 Kotlin 函数&#xff0c;如何从 Java 调用它而无须为每个参数显式指定值&#xff1f; 方案 为函数添加注解JvmOverloads。 也就是为Java添加重载方法&#xff0c;这样Java调用Kotlin的方法时就不用传递全部的参数了。 示例 在 Kotlin …

企业环保创A标准

在环保日益受到重视的今天&#xff0c;企业如何有效地进行环保管理&#xff0c;提高自身的环保水平&#xff0c;已成为一个不可忽视的议题。而企业环保创A标准&#xff0c;正是为了评估企业的环保水平和环保管理能力而制定的一项重要评价标准。朗观视觉小编将详细解析企业环保创…

XILINX 7系列XDMA使用_IP核介绍以及工程搭建

文章目录 一、XDMA IP核1.1、接口说明1.2、配置页说明 二、XDMA工程搭建2.1、BD搭建2.2 Linux下XDMA驱动安装2.3 Linux下使用XDMA进行数据传输 一、XDMA IP核 1.1、接口说明 sys_clk&#xff1a;主机给PCIE提供的时钟信号&#xff0c;通过原理图查看 sys_rst_n&#xff1a;主机…

【已解决】引入 element 组件无法使用编译错误 ERROR Failed to compile with 1 error

如果大家使用这个vue 配合 element 框架不熟练&#xff0c;当你顺利按照文档安装好 vue 和 element 的时候想要使用element 的组件时候确无法展示出来&#xff0c;甚至报错。不妨看看是不是这个问题&#xff0c; 1.首先使用element 的时候&#xff0c;前提是把必须要的 elemen…

TCGAbiolinks包学习

TCGAbiolinks 写在前面学习目的GDCquery GDCdownload GDC prepare中间遇到的报错下载蛋白质数据 写在前面 由于别人提醒我TCGA的数据可以利用TCGAbiolinks下载并处理&#xff0c;所以我决定阅读该包手册&#xff0c;主要是该包应该是有更新的&#xff0c;我看手册进行更新了&…

法国恐脱欧、陷金融危机!股指本周跌6.2%,创三年多最大跌幅

内容提要 法国财政部长警告称&#xff0c;左翼政党联盟若上台可能导致法国脱欧&#xff0c;而且无论极右翼还是左翼上台&#xff0c;都可能导致法国爆发金融危机。由于政坛风险高企&#xff0c;法国股市周五延续跌势&#xff0c;本周已经抹掉2100亿美元市值&#xff0c;几乎回…

MySQL学习——创建MySQL Workbench中的Connections

在MySQL Workbench中&#xff0c;Connections&#xff08;连接&#xff09;是用户与MySQL数据库进行交互的桥梁。 本文将添加一个新连接&#xff0c;该连接可以是初始连接&#xff0c;也可以是附加连接。在开始之前&#xff0c;必须安装、启动MySQL服务器的实例&#xff0c;并…

【单片机毕业设计选题24007】-基于STM32和阿里云的家庭健康数据监测系统

系统功能: 本课题设计是基于STM32单片机作为控制主体&#xff0c;通过HX711称重模块&#xff0c;HC-SR04超声波测距模块&#xff0c;红外测温&#xff0c;心率传感器等模块通过I2C或SPI接口与STM32进行通信&#xff0c;并读取传感器输出的身高&#xff0c;体重&#xff0c;心率…

matlab-2-simulink-小白教程-如何绘制电路图进行电路仿真

以上述电路图为例&#xff1a;包含D触发器&#xff0c;时钟CLK,与非门 一、启动simulink的三种方式 方式1 在MATLAB的命令行窗口输入“Simulink”命令。 方式2 在MATLAB主窗口的“主页”选项卡中&#xff0c;单击“SIMULINK”命令组中的Simulink命令按钮。 方式3 从MATLAB…

FreeRTOS简单内核实现4 临界段

文章目录 0、思考与回答0.1、思考一0.2、思考二0.3、思考三 1、关中断1.1、带返回值1.2、不带返回值 2、开中断3、临界段4、应用 0、思考与回答 0.1、思考一 为什么需要临界段&#xff1f; 有时候我们需要部分代码一旦这开始执行&#xff0c;则不允许任何中断打断&#xff0…

『大模型笔记』Anthropic团队:什么是大模型的可解释性!

Anthropic团队:什么是大模型的可解释性! 文章目录 一. Anthropic团队:什么是大模型的可解释性!二. 参考文献我的小红书中英文双语视频:Anthropic团队:什么是大模型的可解释性!一. Anthropic团队:什么是大模型的可解释性! 我在Anthropic的可解释性团队工作。可解释性是…

【ArcGISProSDK】OpenItemDialog打开文件对话框

打开单个文件 效果 代码 public async void OpenFunction() {// 获取默认数据库var gdbPath Project.Current.DefaultGeodatabasePath;OpenItemDialog openItemDialog new OpenItemDialog() { Title "打开要素文件",InitialLocation gdbPath,Filter ItemFilte…