作者:Grey
原文地址:
(资料图片仅供参考)
博客园:Java SE 20 新增特性
CSDN:Java SE 20 新增特性
源码源仓库: Github:java_new_features
镜像仓库: GitCode:java_new_features
Switch类型匹配(第四次预览)在Java SE 17 新增特性中,Switch 类型匹配作为预览功能推出,到 Java SE 20 ,这个功能已经是第四次预览版,在 Java SE 17 中,可以通过加强 switch 表达式和语句的模式匹配能力,减少了定义这些表达式所需的模板,此外,switch 中增加了空值的支持。如下示例:
注:执行如下代码需要基于 Java SE 17 + ,且增加--enable-preview
参数。
package git.snippets.jdk20;/** * switch类型匹配(二次预览) * * @author Grey * @date 2023/05/03 * @since 20 */public class SwitchMatchTest { public static void main(String[] args) { switchMatch(3); switchMatch("HELLO"); switchMatch("hello world"); switchMatch(null); } static void switchMatch(Object obj) { switch (obj) { case String s when s.length() > 5 -> System.out.println(s.toUpperCase()); case String s -> System.out.println(s.toLowerCase()); case Integer i -> System.out.println(i * i); case null -> System.out.println("null obj"); default -> { } } }}
范围值(Scoped Value,孵化阶段)JEP 429 在 Java SE 20 的孵化阶段引入了范围值(ScopedValue), 范围值可以与虚拟线程很好地结合。它允许在有限的时间内存储一个值,而且只有写入该值的线程可以读取它。类似ThreadLocal对于线程的作用。详见:SCOPED VALUES IN JAVA
record 的匹配增强(第二次预览)record 的匹配增强首次预览在 Java SE 19, record 可以与 instanceof 一起使用,也可以使用 switch 来访问记录的字段,而无需强制转换和调用访问器方法,一个 record 的示例如下
package git.snippets.jdk20;/** * record 模式匹配增强(二次预览) * 需要增加 --enable-preview参数 * * @author Grey * @date 2022/9/22 * @since 19 */public class RecordTest { public static void main(String[] args) { Points points = new Points(1, 2); Line line = new Line(new Points(1, 2), new Points(3, 4)); printPoints(points); printLine(line); } private static void printPoints(Object object) { if (object instanceof Points(int x, int y)) { System.out.println("jdk 19 object is a position, x = " + x + ", y = " + y); } if (object instanceof Points points) { System.out.println("pre jdk 19 object is a position, x = " + points.x() + ", y = " + points.y()); } switch (object) { case Points position -> System.out.println("pre jdk 19 object is a position, x = " + position.x() + ", y = " + position.y()); default -> throw new IllegalStateException("Unexpected value: " + object); } switch (object) { case Points(int x, int y) -> System.out.println(" jdk 19 object is a position, x = " + x + ", y = " + y); default -> throw new IllegalStateException("Unexpected value: " + object); } } public static void printLine(Object object) { if (object instanceof Line(Points(int x1, int y1), Points(int x2, int y2))) { System.out.println("object is a path, x1 = " + x1 + ", y1 = " + y1 + ", x2 = " + x2 + ", y2 = " + y2); } switch (object) { case Line(Points(int x1, int y1), Points(int x2, int y2)) -> System.out.println("object is a path, x1 = " + x1 + ", y1 = " + y1 + ", x2 = " + x2 + ", y2 = " + y2); // other cases ... default -> throw new IllegalStateException("Unexpected value: " + object); } }}record Points(int x, int y) {}record Line(Points from, Points to) {}
此外,在 JEP 432 中,Java SE 20 的 record 支持类型推断,例如,定义了如下数据结构
interface Multi {}record Tuple(T t1, T t2) implements Multi {}record Triple(T t1, T t2, T t3) implements Multi {}
在 Java SE 20 之前,需要这样做
// 需要指定类型 static void preJDK20(Multi multi) { if (multi instanceof Tuple(var s1, var s2)) { System.out.println("Tuple: " + s1 + ", " + s2); } else if (multi instanceof Triple(var s1, var s2, var s3)) { System.out.println("Triple: " + s1 + ", " + s2 + ", " + s3); } }
需要指定类型,例如:本实例需要指定 String 类型。
到了 Java SE 20,record 有类型推断,所以上述代码可以写成
static void JDK20(Multi multi) { if (multi instanceof Tuple(var s1, var s2)) { System.out.println("Tuple: " + s1 + ", " + s2); } else if (multi instanceof Triple(var s1, var s2, var s3)) { System.out.println("Triple: " + s1 + ", " + s2 + ", " + s3); } }
在循环中也可以支持类似的用法,示例如下:
在 Java SE 20 之前
record Position(int x, int y) {}static void preJDK20Loop(List positions) { for (Position p : positions) { System.out.printf("(%d, %d)%n", p.x(), p.y()); }}
在 Java SE 20 版本中,可直接写成如下形式
static void JDK20Loop(List positions) { for (Position(int x, int y) : positions) { System.out.printf("(%d, %d)%n", x, y); } }
此外,在 Java SE 20 中,移除了对 record 命名模式的支持,在 Java SE 19 中,如下写法是对的
if (object instanceof Points(int x, int y) points) { System.out.println("pre jdk 19 object is a position, x = " + points.x() + ", y = " + points.y()); }
但是到了 Java SE 20 ,已经将上述写法废弃,Java SE 20 只支持如下两种写法
if (object instanceof Points(int x, int y)) { System.out.println("jdk 19 object is a position, x = " + x + ", y = " + y); } if (object instanceof Points points) { System.out.println("pre jdk 19 object is a position, x = " + points.x() + ", y = " + points.y()); }
废弃 java.net.URL 的构造方法java.net.URL
的构造函数已被标记为"废弃"。应该使用URI.create(..)
和URI.toURL()
方法。下面是一个例子:
package git.snippets.jdk20;import java.net.URI;import java.net.URL;/** * URL的构造方法被彻底废弃 * * @author Grey * @date 2023/05/03 * @since 20 */public class URLConstructorTest { public static void main(String[] args) throws Exception { // 以下构造方法在 Java SE 20 被彻底废弃 // URL url = new URL("xxx"); // Java SE 20 用如下方法构造 URL URL url = URI.create("xxx").toURL(); }}
更多Java SE 7及以后各版本新增特性,持续更新中...
参考资料Java Language Changes for Java SE 20
JDK 20 Release Notes
JAVA 20 FEATURES(WITH EXAMPLES)
JavaSE20新增特性作者:Grey原文地址:博客园:JavaSE20新增特性CSDN:JavaSE20新增特性源码源仓库:Github
格隆汇5月3日丨海鑫集团(01850 HK)公告,根据通函所载的预期时间表,按连权基准买卖合并股份的最后一天为2023年
仅过去一年,1997年施琼的创业便以失败告终,不仅把前面赚的钱全亏光了,还倒赔了40万元。2002年,施琼还开
1、一种产于鄱阳湖一带的瓜果(打瓜)的籽。2、作为炒货瓜子的一种。本文到此分享完毕,希望对大家有所帮助
X 关闭
前5个月安徽省综合保税区进出口值525亿元 同比增长26.2%
“没坐头”到“天天像过年”:“花儿”唱响西北民众生活变化轨迹
抵返人员发现2例初筛阳性 牡丹江开展区域核酸检测
中企承建尼日利亚最大水电站:年内还将实现3台机组发电目标
安徽淮南新增确诊病例1例、新增无症状感染者50人
X 关闭
上海嘉定体育馆隔离救治点首批新冠病毒感染者顺利“出院”
千里支援显真情 安徽六安捐赠的100余吨新鲜蔬菜抵沪
缉毒英雄蔡晓东烈士安葬仪式在云南西双版纳举行
多方合作推动青海建设国际生态文明高地
海口新增1例确诊病例和2例无症状感染者