Java SE 23 新增特性

作者:Grey

原文地址:

博客园:Java SE 23 新增特性

CSDN:Java SE 23 新增特性

源码

源仓库: Github:java_new_features

Primitive Types in Patterns, instanceof, and switch (预览功能)

通过 instanceof 和 switch,我们可以检查对象是否属于特定类型,如果是,则将该对象绑定到该类型的变量,执行特定的程序路径,并在该程序路径中使用新变量。

public class PrimitiveTypesTest {
void main() {
test1("hello world");
test2("hello world");
test1(56);
test2(56);
test1(java.time.LocalDate.now());
test2(java.time.LocalDate.now());
} private static void test1(Object obj) {
if (obj instanceof String s && s.length() >= 5) {
System.out.println(s.toUpperCase());
} else if (obj instanceof Integer i) {
System.out.println(i * i);
} else {
System.out.println(obj);
}
} private static void test2(Object obj) {
switch (obj) {
case String s when s.length() >= 5 -> System.out.println(s.toUpperCase());
case Integer i -> System.out.println(i * i);
case null, default -> System.out.println(obj);
}
}
}

JEP 455 在 Java 23 中引入了两项变更:

  • 可以在 switch 表达式和语句中使用所有基元类型,包括 long、float、double 和 boolean。

  • 其次,我们还可以在模式匹配中使用所有基元类型,包括 instanceof 和 switch。

在这两种情况下,即通过 long、float、double 和布尔类型进行 switch 以及使用基元变量进行模式匹配时,与所有新的 switch 功能一样,switch 必须要涵盖所有可能的情况。

private static void test3(int x) {
switch (x) {
case 1, 2, 3 -> System.out.println("Low");
case 4, 5, 6 -> System.out.println("Medium");
case 7, 8, 9 -> System.out.println("High");
}
}

Module Import Declarations (模块导入声明,预览功能)

通过简洁地导入模块导出的所有包的功能来增强 Java 编程语言。这简化了模块库的重复使用,但不要求导入代码本身必须在模块中。这是一项预览语言功能。

自 Java 1.0 起,java.lang 包中的所有类都会自动导入到每个 .java 文件中。这就是为什么我们无需导入语句就能使用 ObjectStringIntegerExceptionThread 等类的原因。

我们还可以导入完整的包。例如,导入 java.util.* 意味着我们不必单独导入 ListSetMapArrayListHashSetHashMap 等类。

JEP 467现在允许我们导入完整的模块,更准确地说,是导入模块导出的包中的所有类。

例如,我们可以按如下方式导入完整的 java.base 模块,然后使用该模块中的类(例如 ListMapCollectorsStream),而无需进一步导入:

package git.snippets.jdk23;

import module java.base;

public class ModuleImportDeclarationsTest {
void main() {
System.out.println(groupByFirstLetter("a", "abc", "bcd", "ddd", "dddc", "dfc", "bc"));
} public static Map<Character, List<String>> groupByFirstLetter(String... values) {
return Stream.of(values).collect(Collectors.groupingBy(s -> Character.toUpperCase(s.charAt(0))));
}
}

如果有两个同名的导入类,例如下面示例中的 Date,编译器就会出错:

import module java.base;
import module java.sql;

如果一个导入模块临时导入了另一个模块,那么我们也可以使用临时导入模块导出包中的所有类,而无需显式导入。

例如,java.sql 模块转义导入了 java.xml 模块:

module java.sql {
. . .
requires transitive java.xml;
. . .
}

因此,在下面的示例中,我们不需要显式导入 SAXParserFactory 和 SAXParser,也不需要显式导入 java.xml 模块:

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

Flexible Constructor Bodies (二次预览)

在 JDK 23 之前,下述代码中,Child1的构造函数,只能先通过super构造父类,然后才能初始化子类的 b 这个变量。

public class FlexibleConstructorBodies {
void main() {
new Child1(1, 2);
}
} class Parent {
private final int a; public Parent(int a) {
this.a = a;
printMe();
} void printMe() {
System.out.println("a = " + a);
}
} // JDK 23 之前
class Child1 extends Parent {
private final int b; public Child1(int a, int b) {
super(verifyParamsAndReturnA(a, b));
this.b = b;
} @Override
void printMe() {
super.printMe();
System.out.println("b = " + b);
} private static int verifyParamsAndReturnA(int a, int b) {
if (a < 0 || b < 0) throw new IllegalArgumentException();
return a;
}
}

当我们执行

new Child1(1,2);

这段代码的时候,本来我们期待返回的是

a = 1
b = 2

但是由于父类在构造时候调用了printMe(),且这个调用是在 b 变量初始化之前调用的,所以导致程序执行的结果是

a = 1
b = 0

今后,在使用 super(...) 调用超级构造函数之前,以及在使用 this(...) 调用替代构造函数之前,我们可以执行任何不访问当前构造实例(即不访问其字段)的代码

此外,我们还可以初始化正在构造的实例的字段。详见JEP 482

在 JDK 23 上,上述代码可以调整为:

class Child2 extends Parent {
private final int b; public Child2(int a, int b) {
if (a < 0 || b < 0) throw new IllegalArgumentException(); // ⟵ Now allowed!
this.b = b; // ⟵ Now allowed!
super(a);
} @Override
void printMe() {
super.printMe();
System.out.println("b = " + b);
}
}

其中构造函数中,a和b的初始化和判断,都可以在super(...)函数调用之前,

执行

new Child2(1,2);

打印结果为预期结果

a = 1
b = 2

Implicitly Declared Classes and Instance Main Methods (第三次预览)

最早出现在 JDK 21 中,见Java SE 21 新增特性

原来我们写一个main方法,需要

public class UnnamedClassesAndInstanceMainMethodsTest {

    public static void main(String[] args) {
System.out.println("Hello World!");
} }

而且Java文件的名称需要和UnnamedClassesAndInstanceMainMethodsTest保持一致,到了JDK 23,上述代码可以简化成

void main() {
System.out.println("hello world");
}

甚至连 public class ... 这段也不需要写。

更多

Java SE 7及以后各版本新增特性,持续更新中...

参考资料

Java Language Changes for Java SE 23

JDK 23 Release Notes

JAVA 23 FEATURES(WITH EXAMPLES

Java SE 23 新增特性的更多相关文章

  1. Java SE 8 新增特性

    Java SE 8 新增特性 作者:Grey 原文地址: Java SE 8 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...

  2. Java SE 10 新增特性

    Java SE 10 新增特性 作者:Grey 原文地址:Java SE 10 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  3. Java SE 9 新增特性

    Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...

  4. Java SE 11 新增特性

    Java SE 11 新增特性 作者:Grey 原文地址:Java SE 11 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  5. Java SE 12 新增特性

    Java SE 12 新增特性 作者:Grey 原文地址:Java SE 12 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  6. Java SE 13 新增特性

    Java SE 13 新增特性 作者:Grey 原文地址:Java SE 13 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  7. Java SE 14 新增特性

    Java SE 14 新增特性 作者:Grey 原文地址:Java SE 14 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  8. Java SE 15 新增特性

    Java SE 15 新增特性 作者:Grey 原文地址:Java SE 15 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  9. Java SE 16 新增特性

    Java SE 16 新增特性 作者:Grey 原文地址:Java SE 16 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  10. Java SE 17 新增特性

    Java SE 17 新增特性 作者:Grey 原文地址:Java SE 17 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

随机推荐

  1. TypeScript 学习笔记 — 类型推断和类型保护(十一)

    目录 类型推断 1.赋值推断 2.返回值推断 3.函数推断(反向推断) 4.属性推断 5.类型反推 6.索引访问操作符 7.类型映射 类型保护 1.typeof 类型保护 2.instanceof 类 ...

  2. Pycharm中开发vue element项目时eslint的安装和使用

    在PyCharm中使用ESLint对Element UI进行语法检查和代码风格检查的配置步骤如下: 确保你的项目已经配置了ESLint并且可以正常运行.如果尚未安装ESLint,请先使用npm(或者你 ...

  3. [NOIP2008 提高组] 笨小猴(洛谷题号P1125)

    [NOIP2008 提高组] 笨小猴 题目描述 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼.但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描 ...

  4. jmeter目录结构含义

    backups :脚本备份目录.格式JMXbin目录∶存放Jmeter的启动脚本,配置文件.模块文件.jmeter.bat启动Jmeterjmeter.properties核心配置文件.docs:离线 ...

  5. RIME:用交叉熵 loss 大小分辨 preference 是否正确 + 内在奖励预训练 reward model

    文章题目:RIME: Robust Preference-based Reinforcement Learning with Noisy Preferences,ICML 2024 Spotlight ...

  6. 一款.NET开源、跨平台的DASH/HLS/MSS下载工具

    前言 今天大姚给大家分享一款.NET开源(MIT License).免费.跨平台的DASH/HLS/MSS下载工具,并且支持点播和直播(DASH/HLS)的内容下载:N_m3u8DL-RE. 网络流媒 ...

  7. SEO初学指南之关键词研究(3) - 关键词分析实战

    经过之前的学习,这次我们开始实战.手把手教大家如何为网站筛选符合条件的关键词. 还不熟练的,建议再反复学习前两篇文章: SEO初学指南之关键词研究 (1) - 入门 SEO初学指南之关键词研究 (2) ...

  8. Hyperledger Fabric 2.x 环境搭建

    一.说明 区块链网络的核心是分布式账本,在这个账本中记录了网络中发生的所有交易信息. Hyperledger Fabric是一个是开源的,企业级的,带权限的分布式账本解决方案的平台.Hyperledg ...

  9. 痞子衡嵌入式:MCUXpresso IDE下在线联合调试i.MXRT1170双核工程的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下在线联合调试i.MXRT1170双核工程的三种方法. 两年前痞子衡写过一篇<i.MXRT1170下在 ...

  10. 【SpringCloud】Nacos集群部署(Centos平台)

    一.前提环境准备 Nacos 下载 https://github.com/alibaba/nacos/releases 或者使用其它博主备份的 https://blog.csdn.net/weixin ...