JDK14新特征最全详解

JDK 14一共发行了16个JEP(JDK Enhancement Proposals,JDK 增强提案),筛选出JDK 14新特性。

- 343: 打包工具 (Incubator)

- 345: G1的NUMA内存分配优化

- 349: JFR事件流

- 352: 非原子性的字节缓冲区映射

- 358: 友好的空指针异常

- 359: Records (预览)

- 361: Switch表达式 (标准)

- 362: 弃用Solaris和SPARC端口

- 363: 移除CMS(Concurrent Mark Sweep)垃圾收集器

- 364: macOS系统上的ZGC

- 365: Windows系统上的ZGC

- 366: 弃用ParallelScavenge + SerialOld GC组合

- 367: 移除Pack200 Tools 和 API

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

- 370: 外部存储器API (Incubator)

1 JEP 305的instanceof运算符

JEP 305新增使instanceof运算符具有模式匹配的能力。模式匹配使程序通用逻辑更简洁,代码更简单,同时在做类型判断和类型转换时也更安全。

设计初衷

包含判断表达式是否具有某种类型的逻辑时,程序会对不同类型进行不同的处理。

instanceof-and-cast

// 在方法的入口接收一个对象
public void beforeWay(Object obj) {// 通过instanceof判断obj对象的真实数据类型是否是String类型if (obj instanceof String) {// 如果进来了,说明obj的类型是String类型,直接进行强制类型转换。String str = (String) obj;// 输出字符串的长度System.out.println(str.length());}
}
  1. 先判断obj的真实数据类型
  2. 判断成立后进行了强制类型转换(将对象obj强制类型转换为String)
  3. 声明一个新的本地变量str,指向上面的obj

但上述做法不是最理想:

  • 语法臃肿乏味
  • 同时执行类型检测校验和类型转换
  • String类型出现3次,但最终要的可能只是一个String类型的对象变量
  • 重复代码过多,冗余度高

JDK14提供新解决方案:新的instanceof模式匹配 ,用法如下,在instanceof的类型之后添加变量str

instanceofobj的类型检查通过,obj会被转换成str表示的String类型。在新用法中,String类型仅出现一次:

public void patternMatching(Object obj) {if (obj instanceof String str) {// can use str hereSystem.out.println(str.length());} else {// can't use str here}
}

注意:若obj是String类型,则将obj类型转换为String,并将其赋值给变量str。绑定的变量作用域为if语句内部,并不在false语句块内。

简化equals()

equals()一般先检查目标对象的类型。instanceof的模式匹配可简化equals()实现。

public class Student {private  String name ;public Student(String name) {this.name = name;}//    @Override
//    public boolean equals(Object o) {
//        if (this == o) return true;
//        if (o == null || getClass() != o.getClass()) return false;
//        Student student = (Student) o;
//        return Objects.equals(name, student.name);
//    }// 简化后做法!  @Overridepublic boolean equals(Object obj) {return (obj instanceof Student s) && Objects.equals(this.name, s.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
}

JDK 14后的instanceof的模式匹配极大的简化了类型检查和转型的问题。

2 JEP 361:Switch Expressions (Standard)

扩展switch分支选择语句的写法。Switch表达式在经过JDK 12(JEP 325)和JDK(JEP 354)的预览之后,在JDK 14中已稳定可用。

2.1 设计初衷

switch语句是个变化较大的语法。可是因为Java switch一直不够强大、熟悉swift或js语言的同学可对比发现,因为Java的很多版本都在不断改进switch语句:JDK 12扩展了switch语句,使其可用作语句或表达式,并且传统的和扩展的简化版switch都可以使用。

JDK 12对于switch的增强主要在于简化书写形式,提升功能点。

2.2 switch的进化

  • Java 5+开始,可用枚举
  • Java 7+开始,支持使用String类型的变量和表达式
  • Java 11+开始,自动对省略break导致的贯穿提示警告(以前需用-X:fallthrough选项才能显示)

从JDK12开始有大程度增强,JDK 14的该JEP是从JEP 325和JEP 354演变而来。但是,此JEP 361 Switch表达式 (标准)是独立的,并不依赖于这俩JEP。

2.3 以前的switch程序

public class Demo01 {public static void main(String[] args){// 声明变量score,并为其赋值为'C'var score = 'C';// 执行switch分支语句switch (score) {case 'A':System.out.println("优秀");break;case 'B':System.out.println("良好");break;case 'C':System.out.println("中");break;case 'D':System.out.println("及格");break;case 'E':System.out.println("不及格");break;default:System.out.println("数据非法!");}}
}

经典的Java 11前的写法 ,不能忘写break,否则switch就会贯穿、导致程序出现错误(JDK 11会提示警告)。

2.4 无需break

在JDK 12前switch忘写break将导致贯穿,在JDK 12对switch的这一贯穿性做了改进。只要将case后面的":"改成箭头,即使不写break也不会贯穿,因此上面程序可改写为:

public class Demo02{public static void main(String[] args){// 声明变量score,并为其赋值为'C'var score = 'C';// 执行switch分支语句switch (score){case 'A' -> System.out.println("优秀");case 'B' -> System.out.println("良好");case 'C' -> System.out.println("中");case 'D' -> System.out.println("及格");case 'E' -> System.out.println("不及格");default -> System.out.println("成绩数据非法!");}}
}

简洁很多了。注意,新老语法不能混用了,否则编译报错:

java: 在 switch 中使用了不同 case 类型:

2.5 JDK 14的switch表达式

JDK 12后的switch甚至可作为表达式,不再是单独的语句,如:

public class Demo03 {public static void main(String[] args) {// 声明变量score,并为其赋值为'C'var score = 'C';// 执行switch分支语句String s = switch (score){case 'A' -> "优秀";case 'B' -> "良好";case 'C' -> "中";case 'D' -> "及格";case 'F' -> "不及格";default -> "成绩输入错误";};System.out.println(s);}
}

上面程序直接将switch表达式的值赋值给s变量,这样switch不再是一个语句,而是一个表达式。

2.6 多值匹配

当你把switch中的case后的冒号改为箭头之后,此时switch就不会贯穿,但某些情况,程序本就希望贯穿。比如希望两个case共用一个执行体!

JDK 12之后的switch中的case也支持多值匹配,这样程序就变得更加简洁了,如:

public class Demo04 {public static void main(String[] args) {// 声明变量score,并为其赋值为'C'var score = 'B';// 执行switch分支语句String s = switch (score){case 'A', 'B' -> "上等";case 'C' -> "中等";case 'D', 'E' -> "下等";default -> "成绩数据输入非法!";};System.out.println(s);}
}

2.7 Yielding a value

用箭头标签时,箭头标签右边可为表达式、throw语句或是代码块。

如是代码块,需用yield语句来返回值。下面代码中的print方法中的default语句的右边是一个代码块。在代码块中使用yield来返回值。

JDK 14引入yield语句产生一个值,该值成为封闭的switch表达式的值。

public void print(int days) {// 声明变量score,并为其赋值为'C'var score = 'B';String result = switch (score) {case 'A', 'B' -> "上等";case 'C' -> "中等";case 'D', 'E' -> "下等";default -> {if (score > 100) {yield "数据不能超过100";} else {yield score + "此分数低于0分";}}};System.out.println(result);
}

在switch表达式中不能使用break。switch表达式的每个标签都必须产生一个值或抛异常。

switch表达式须穷尽所有可能值。这意味着通常需要一个default语句。一个例外是枚举类型,如穷尽了枚举类型的所有可能值,则不需要使用default。在这种情况下,编译器会自动生成一个default语句。这是因为枚举类型中的枚举值可能发生变化。

如枚举类型Color 中原来只有3个值:RED、GREEN和BLUE。使用该枚举类型的switch表达式穷尽了3种情况并完成编译。之后Color中增加了一个新的值YELLOW,当用这个新的值调用之前的代码时,由于不能匹配已有的值,编译器产生的default会被调用,告知枚举类型发生改变

3 JEP 368:文本块 (JDK 13后的第二个预览版)

3.1 引入

Java开发通常需进行大量字符串文本拼接等相关组织操作,从JDK 13到JDK 14开始文本块新特性,提高Java程序书写大段字符串文本的可读性和方便性。

3.2 设计初衷

文本块功能在JDK 13中作为预览功能(JEP 355)被引入。这个功能在JDK 14中得到了更新。文本块是使用3个引号分隔的多行字符串。

3.3 描述

文本块可表示任何字符串,具有更高表达能力和更少复杂度。

文本块开头定界符是("""),后面跟0或多个空格,最后跟一个行终止符。内容从开头定界符的行终止符之后的第一个字符开始。结束定界符也是(""")。内容在结束定界符的第一个双引号之前的最后一个字符处结束。

与字符串文字中的字符不同,文本块的内容中可以直接包含双引号字符。当然也允许在文本块中使用\“,但不是必需也不建议用。与字符串文字中的字符不同,内容可以直接包含行终止符。允许在文本块中用\n,但不是必需也不建议用。

如文本块:

line 1
line 2
line 3

就等效于字符串文字:

"line 1\nline 2\nline 3\n"

或字符串文字的串联:

"line 1\n" +
"line 2\n" +
"line 3\n"

文本块功能在JDK 13中作为预览功能(JEP 355)被引入。这个功能在JDK 14中得到了更新。文本块是使用3个引号分隔的多行字符串。根据文本块在源代码中的出现形式,多余的用于缩进的白字符会被去掉。相应的算法会在每一行中去掉同样数量的白字符,直到其中任意的一行遇到非白字符为止。每一行字符串末尾的白字符会被自动去掉。

下面代码中的文本块xml会被去掉前面的2个白字符的缩进。

String xml = """<root><a>Hello</a><b><c><d>World</d></c></b></root>""";

缩进的去除是要考虑到作为结束分隔符的3个引号的位置的。如果把上面的文本块改成下面代码的格式,则没有缩进会被去掉。注意最后一行中3个引号的位置。去除的白字符的数量需要考虑到全部行中前导的白字符数量,包括最后一行。最终去除的白字符数量是这些行中前导白字符数量的最小值。

String xml2 = """<root><a>Hello</a><b><c><d>World</d></c></b></root>
""";

在文本块中同样可以使用\n和\r这样的转义字符。除了String本身支持的转义字符之外,文本块还支持2个特殊的转义字符:

- \:阻止插入换行符。

- \s:表示一个空格。可以用来避免末尾的白字符被去掉。

由于\的使用,下面代码中的longString实际上只有一行。

String longString = """hello \world \goodbye""";

在下面的代码中,通过使用\s,每一行的长度都为10。

String names = """alex     \sbob      \slong name\s""";

3.4 HTML

使用原始字符串语法:

String html = "<html>\n" +"    <body>\n" +"        <p>Hello, world</p>\n" +"    </body>\n" +"</html>\n";

使用文本块文本块语法:

String html = """<html><body><p>Hello, world</p></body></html>""";

3.5 SQL

原始的字符串语法:

String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +"WHERE `CITY` = 'INDIANAPOLIS'\n" +"ORDER BY `EMP_ID`, `LAST_NAME`;\n";

文本块语法:

String query = """SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`WHERE `CITY` = 'INDIANAPOLIS'ORDER BY `EMP_ID`, `LAST_NAME`;""";

3.6 多语言示例

原始字符串语法:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("function hello() {\n" +"    print('\"Hello, world\"');\n" +"}\n" +"\n" +"hello();\n");

文本块语法:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""function hello() {print('"Hello, world"');}hello();""");

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化

  • 活动&券等营销中台建设

  • 交易平台及数据中台等架构和开发设计

  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化

  • LLM Agent应用开发

  • 区块链应用开发

    目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考:

  • 编程严选网

本文由博客一文多发平台 OpenWrite 发布!

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

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

相关文章

【JavaScript】解决 JavaScript 语言报错:Uncaught TypeError: XYZ is not iterable

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 对非数组类型使用 for...of 循环2. 对非可迭代对象使用扩展运算符3. 在 Promise.all 中传递非可迭代对象4. 使用解构赋值时&#xff0c;右侧值非可迭代 四、解决方案与预防措施1. 确保使用可迭代对象2. 使用…

各种Attention|即插即用|适用于YoloV5、V7、V8、V9、V10(一)

摘要 本文总结了各种注意力&#xff0c;即插即用&#xff0c;方便大家将注意力加到自己的论文中。 SE import torch from torch import nn class SEAttention(nn.Module): """ SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;中的注意力…

C++进阶(while循环——函数应用)

知识点代码框架总结 输入n组数据 &#xff0c;对n组数据里面的每一组进行处理&#xff08;输出、求和 、运算、其他&#xff09; int n;//几组数据cin >> n;//2while(n--){//对每组数据进行处理}看到下面的样例&#xff0c;肌肉型反映出上面的框架//2// 1 2 3// 4 5 6若…

虚拟机:VMware功能,安装与使用

目录 一、虚拟机介绍 二、VMware 1.介绍 2.安装 &#xff08;1&#xff09;根据提示按步骤安装​编辑 &#xff08;2&#xff09;更改软件的安装地址​编辑 &#xff08;3&#xff09;根据自己的需求选择是否需要软件更新​编辑 &#xff08;4&#xff09;根据需求选择…

自动驾驶中的人机互相接管问题讨论

一、背景 人机接管&#xff08;human takeover&#xff09;是指在自动驾驶过程中&#xff0c;当系统遇到超出其处理能力或预设安全阈值的情况时&#xff0c;将控制权交还给驾驶员的过程。这一环节的设计直接关系到自动驾驶技术的实用性与安全性&#xff0c;是目前研究和实践中…

【SQL】MySQL事务的隔离级别和幻读、脏读和不可重复读

事务的隔离级别是数据库管理系统提供的一种功能&#xff0c;用于控制事务之间的相互影响程度。常见的隔离级别包括&#xff1a; 读未提交 (Read Uncommitted)&#xff1a;允许一个事务读取另一个事务未提交的数据。 读已提交 (Read Committed)&#xff1a;一个事务只能读取另一…

Python应用爬虫下载QQ音乐歌曲!

目录&#xff1a; 1.简介怎样实现下载QQ音乐的过程&#xff1b; 2.代码 1.下载QQ音乐的过程 首先我们先来到QQ音乐的官网&#xff1a; https://y.qq.com/&#xff0c;在搜索栏上输入一首歌曲的名称&#xff1b; 如我在上输入最美的期待&#xff0c;按回车来到这个画面 我们首…

[USACO24OPEN] Smaller Averages G (单调性优化dp)

来源 题目 Bessie 有两个长度为 N的数组&#xff08;1≤N≤500&#xff09;。第一个数组的第 i 个元素为 ai​&#xff08;1≤ai​≤10^6&#xff09;&#xff0c;第二个数组的第 i个元素为bi​&#xff08;1≤bi​≤10^6&#xff09;。 Bessie 希望将两个数组均划分为若干非空…

机器学习(五) -- 监督学习(6) --逻辑回归

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;5&#xff09; -- 线性回归2 下篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;7&#xff09; --SVM1 前言 tips&#xff1a;标题前有“***”的内…

uniapp 支付宝小程序 芝麻免押 免押金

orderStr参数如下&#xff1a; my.tradePay({orderStr:res, // 完整的支付参数拼接成的字符串&#xff0c;从 alipay.fund.auth.order.app.freeze 接口获取success: (res) > {console.log(免押成功);console.log(JSON.stringify(res),不是JOSN);console.log(JSON.stringify…

使用机器学习 最近邻算法(Nearest Neighbors)进行点云分析 (scikit-learn Open3D numpy)

使用 NearestNeighbors 进行点云分析 在数据分析和机器学习领域&#xff0c;最近邻算法&#xff08;Nearest Neighbors&#xff09;是一种常用的非参数方法。它广泛应用于分类、回归和聚类分析等任务。下面将介绍如何使用 scikit-learn 库中的 NearestNeighbors 类来进行点云数…

[GICv3] 3. 物理中断处理(Physical Interrupt Handling)

中断生命周期 ​​ 外设通过中断信号线生成中断&#xff0c;或者软件生成中断&#xff08;SGI&#xff09;。Distributor 和 ReDistributor 配合按照中断分组和中断优先级仲裁后将最高优先级的中断分发到 CPU interface。cpu interface 向中断发送到 PEPE 读取 IAR 寄存器&am…

使用Java连接星火认知大模型:一个实际案例解析

引言&#xff1a; 随着人工智能技术的快速发展&#xff0c;认知大模型如星火在自然语言处理、语音识别等领域发挥着越来越重要的作用。本文将通过一个实际的Java代码示例&#xff0c;详细讲解如何使用Java连接星火认知大模型&#xff0c;并处理其响应。 1.导入依赖&#xff1…

【防火墙】防火墙安全策略用户认证综合实验

实验拓扑及要求 拓扑搭建及IP配置 防火墙&#xff08;总公司&#xff09;和交换机&#xff08;汇聚生产区和办公区&#xff09;的接口配置 生产区在vlan2&#xff0c;办公区在vlan3&#xff0c;防火墙在G1/0/3接口上创建子接口G1/0/3.1和G1/0/3.2对两个区域分别进行管理 交换…

全国297个地级市 2006年-2021年 绿地面积、建成区绿化覆盖率(数据整理)

城市绿化覆盖数据&#xff1a;评估生态环境与生活质量的指标 城市绿化是衡量一个城市生态环境质量和居民生活质量的重要指标。绿地面积和建成区绿化覆盖率是两个关键的数据点&#xff0c;它们提供了对城市绿化状况的直接观察。 绿地面积与建成区绿化覆盖率的定义&#xff1a;…

【postgresql】锁

PostgreSQL 提供了多种锁模式来控制对表和行的并发访问&#xff0c;以确保数据的一致性和完整性。这些锁模式包括表级锁和行级锁&#xff0c;它们可以由应用程序显式控制&#xff0c;也可以在执行大多数 PostgreSQL 命令时自动获取。 锁类型 PostgreSQL类型的锁包括&#xff…

数据结构(Java):树二叉树

目录 1、树型结构 1.1 树的概念 1.2 如何判断树与非树 1.3 树的相关概念 1.4 树的表示形式 1.4.1 孩子兄弟表示法 2、二叉树 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 二叉树的遍历 1、树型结构 1.1 树的概念 树型结构是一种非线…

prompt第二讲-langchain实现中英翻译助手

文章目录 prompt模板 (prompt template)langchain 中的prompt模板 (prompt template)langchain实现中英翻译助手 prompt模板 (prompt template) 开篇我介绍了在llm中&#xff0c;通常输入的那个字符串会被我们称之为prompt&#xff0c;下面就是一个中英文翻译助手的prompt例子…

【Three.js基础学习】16.Physice

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾 物理库 3D Ammo.js Cannon.js Oimo.js 2D Matter.js P2.js Planck.js Box2D.js 补充:一些看似3D的效果实际使用2D库来实现的 物理 和 three.js的结合 概念补充…

Java核心篇之JVM探秘:对象创建与内存分配机制

系列文章目录 第一章 Java核心篇之JVM探秘&#xff1a;内存模型与管理初探 第二章 Java核心篇之JVM探秘&#xff1a;对象创建与内存分配机制 第三章 Java核心篇之JVM探秘&#xff1a;垃圾回收算法与垃圾收集器 第四章 Java核心篇之JVM调优实战&#xff1a;Arthas工具使用及…