• Java SE 22 新增特性


    Java SE 22 新增特性

    作者:Grey

    原文地址:

    博客园:Java SE 22 新增特性

    CSDN:Java SE 22 新增特性

    源码#

    源仓库: Github:java_new_features

    使用未命名的变量和模式#

    我们经常需要定义一些我们根本不需要的变量。常见的例子包括异常、lambda表达式,例如:

    try {
        String string = "xx";
        int number = Integer.parseInt(string);
    } catch (NumberFormatException e) {
        System.err.println("Not a number");
    }
    

    如果异常变量 e 无须使用,那么上述例子中的变量 e 可以用 _ 代替

    try {
        String string = "xx";
        int number = Integer.parseInt(string);
    } catch (NumberFormatException _) {
        System.err.println("Not a number");
    }
    

    这个功能在 Java SE 21 中作为预览功能发布,详见Java SE 21 新增特性,在 Java 22 中通过 JEP 456 最终确定,不会有任何更改。

    启动多文件源代码程序#

    自 Java 11 起,我们可以直接执行仅由一个文件组成的 Java 程序,而无需先对其进行编译,详见Java SE 11 新增特性

    例如,在 Hello.java 文件中保存一次以下 Java 代码:

    public class Hello {
      public static void main(String[] args) {
        System.out.printf("Hello %s!%n", args[0])}
    }
    

    不需要 javac 编译这个程序,而是可以直接运行它:

    java Hello.java
    

    我们也可以在 Hello.java 文件中定义多个类。但是,随着程序的增长,这种做法很快就会变得混乱;其他类应该定义在单独的文件中,并以合理的包结构组织起来。

    然而,一旦我们添加更多的 Java 文件,Java 11 中所谓的 "启动单个文件源代码 "机制就不再起作用了。

    比如定义两个类:

    public class Hello {
      public static void main(String[] args) {
        System.out.println(Greetings.greet(args[0]));
      }
    }
    
    public class Greetings {
      public static String greet(String name) {
        return "Hello %s!%n".formatted(name);
      }
    }
    

    在 Java SE 11 中,无法执行,因为只支持单个 Java 文件运行,但是到了 Java SE 22,可以支持多个文件源码运行,比如上述两个类,在 Java SE 22 下,可以通过

    java Hello.java
    

    运行。

    Foreign Function 和 Memory API#

    Project Panama中,取代繁琐、易出错、速度慢的 Java 本地接口(JNI)的工作已经进行了很长时间。

    在 Java 14 和 Java 16 中已经引入了 "外来内存访问 API "和 "外来链接器 API"--最初都是单独处于孵化阶段。在 Java 17 中,这些 API 被合并为 "Foreign Function & Memory API"(FFM API),直到 Java 18,它一直处于孵化阶段。

    在 Java 19 中,JDK Enhancement Proposal 424最终将新的 API 提升到了预览阶段,

    在 Java SE 22 中,外来函数与内存 API 终于由 JDK Enhancement Proposal 454 最终确定。

    FFM API 可以直接从 Java 访问本地内存(即 Java 堆外的内存)和访问本地代码(如 C 库)。

    下面是一个简单的例子,它在堆外内存中存储一个字符串,并对其调用 C 语言标准库的 "strlen "函数。

    package git.snippets.jdk22;
    
    import java.lang.foreign.*;
    import java.lang.invoke.MethodHandle;
    
    
    /**
     * FFM API
     * @since 22
     */
    public class FFMTest {
        public static void main(String[] args) throws Throwable {
            // 1. Get a lookup object for commonly used libraries
            SymbolLookup stdlib = Linker.nativeLinker().defaultLookup();
            // 2. Get a handle to the "strlen" function in the C standard library
            MethodHandle strlen = Linker.nativeLinker().downcallHandle(stdlib.find("strlen").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
    
            // 3. Get a confined memory area (one that we can close explicitly)
            try (Arena offHeap = Arena.ofConfined()) {
    
                // 4. Convert the Java String to a C string and store it in off-heap memory
                MemorySegment str = offHeap.allocateFrom("Happy Coding!");
    
                // 5. Invoke the foreign function
                long len = (long) strlen.invoke(str);
                System.out.println("len = " + len);
            }
            // 6. Off-heap memory is deallocated at end of try-with-resources
        }
    }
    
    

    本地化列表#

    Java SE 22 有了新的 ListFormat 类,我们就可以像在连续文本中一样,将列表格式化为枚举。

    package git.snippets.jdk22;
    
    import static java.text.ListFormat.*;
    
    import java.text.ListFormat;
    import java.util.List;
    import java.util.Locale;
    
    public class LocaleDependentListPatternsTest {
        void main() {
            List<String> list = List.of("Earth", "Wind", "Fire");
            System.out.println(ListFormat.getInstance(Locale.CHINA, Type.STANDARD, Style.FULL).format(list));
            System.out.println(ListFormat.getInstance(Locale.US, Type.STANDARD, Style.FULL).format(list));
            System.out.println(ListFormat.getInstance(Locale.GERMAN, Type.STANDARD, Style.FULL).format(list));
            System.out.println(ListFormat.getInstance(Locale.FRANCE, Type.STANDARD, Style.FULL).format(list));
        }
    }
    
    

    运行输出结果

    EarthWindFire
    Earth, Wind, and Fire
    Earth, Wind und Fire
    Earth, Wind et Fire
    

    上述例子表明在不同的 Lacale 设置下,可自动根据配置进行格式化。

    更多#

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

    参考资料#

    Java Language Changes for Java SE 22

    JDK 22 Release Notes

    JAVA 22 FEATURES(WITH EXAMPLES

  • 相关阅读:
    【重温设计模式】迭代器模式及其Java示例
    行为型模式-模板方法模式
    YOLOV8目标检测——最全最完整模型训练过程记录
    KVM虚拟化进阶--KVM设备高级管理
    Redis数据结构之ziplist
    Kestra:高性能、基于 Java 的编排平台
    2.3 如何使用FlinkSQL读取&写入到JDBC(MySQL)
    ZipInputStream解压报错java.lang.IllegalArgumentException: MALFORMED
    Unity之手游UI的点击和方向移动
    《嵌入式 – GD32开发实战指南》第16章 RTC
  • 原文地址:https://www.cnblogs.com/greyzeng/p/18084202