• Java SE 18 新增特性


    Java SE 18 新增特性

    作者:Grey

    原文地址:

    博客园:Java SE 18 新增特性

    CSDN:Java SE 18 新增特性

    源码

    源仓库: Github:java_new_features

    镜像仓库: GitCode:java_new_features

    默认使用 UFT-8 编码

    在 Java SE 18 之前的 Java中,标准字符集会因操作系统和语言设置的不同而不同。Java 标准字符集决定了在 JDK 类库的许多方法中如何将字符串转换为字节,反之亦然(例如,在写入和读取文本文件时)。这些方法包括:

    • FileReader, FileWriter, InputStreamReader, OutputStreamWriter的构造函数。

    • FormatterScanner的构造函数。

    • URLEncoder.encode()URLDecoder.decode()的静态方法。

    当一个应用程序在一个环境中被开发和测试,然后在另一个环境中运行( Java 选择了不同的默认字符集),这可能导致不可预测的行为。

    此外,由于较新的类库方法在没有指定字符集的情况下总是使用 UTF-8 ,所以变得更加混乱,例如:
    Files.writeString(),Files.readString(),Files.newBufferedWriter()Files.newBufferedReader()

    为了保护应用程序免受此类错误的影响,有两种解决方案:

    方案一:在调用所有将字符串转换成字节的方法时指定字符集,反之亦然。

    FileWriter fw = new FileWriter("happy-coding.txt", StandardCharsets.UTF_8);
    // ...
    FileReader fr = new FileReader("happy-coding.txt", StandardCharsets.UTF_8);
    // ...
    Files.readString(Path.of("happy-coding.txt"), StandardCharsets.UTF_8);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这个方案会导致大量的代码重复,容易出错。

    方案二:通过系统属性 "file.encoding "设置默认字符集。

    这种方案中的属性值在 Java SE 17 之前(包括 Java SE 17 )中没有正式记录(见system-properties)。

    其次,如上所述,指定的字符集并不用于所有的 API 方法。比如:

    public class Jep400Example {
      public static void main(String[] args) throws IOException {
        try (FileWriter fw = new FileWriter("happy-coding.txt");
            BufferedWriter bw = new BufferedWriter(fw)) {
          bw.write("ハッピーコーディング!");
        }
    
        String text = Files.readString(Path.of("happy-coding.txt"));
        System.out.println(text);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    让我们用标准编码 US-ASCII 来运行一次该程序。

    java -Dfile.encoding=US-ASCII Jep400Example.java
    
    • 1

    运行结果如下

    ?????????????????????????????????
    
    • 1

    结果是垃圾,因为 FileWriter 考虑到了默认编码,但Files.readString()忽略了它,总是使用UTF-8。只有在你统一使用 UTF-8 的情况下才能正常运行。

    java -Dfile.encoding=UTF-8 Jep400Example.java
    
    • 1

    运行结果如下

    ハッピーコーディング!?
    
    • 1

    在 Java SE 18 中,无论操作系统、地域和语言设置如何,默认编码将始终是 UTF-8,见:JEP 400

    另外,系统属性file.encoding也可以被合法使用。然而,我们应该谨慎地这样做。

    最好的方法是将-Dfile.encoding设置为 UTF-8 或完全省略它。

    代码示例

    package git.snippets.jdk18;
    
    import java.nio.charset.Charset;
    
    public class UFT8Test {
        public static void main(String[] args) {
            System.out.println("Default charset : " + Charset.defaultCharset());
            System.out.println("file.encoding   : " + System.getProperty("file.encoding"));
            System.out.println("native.encoding : " + System.getProperty("native.encoding"));
            System.out.println(Charset.defaultCharset());
            System.out.println("你好");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出结果为:

    Default charset : UTF-8
    file.encoding   : UTF-8
    native.encoding : GBK
    UTF-8
    你好
    
    • 1
    • 2
    • 3
    • 4
    • 5

    JDK 自带 Web Server

    准备一个html页面,放到任意文件夹中,

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Java自带的WebServertitle>
    head>
    <body>
    Web Server By JDK18
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    然后在这个文件所在目录执行

    C:\jdk\jdk-18\bin\jwebserver.exe
    
    • 1

    启动后,控制台会打印如下信息

    Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
    Serving C:\workspace\java_new_features\jdk18_features\src\main\resources and subdirectories on 127.0.0.1 port 8000
    URL http://127.0.0.1:8000/
    
    • 1
    • 2
    • 3

    访问http://127.0.0.1:8000/可以看到效果

    image

    API 文档注释中支持代码片段

    如果我们想把多行代码片段集成到 JavaDoc 中,我们必须通过

    ...
    来完成,而且必须与{@code ...}相结合,这样做非常麻烦

    下面是一个使用

    标签的例子:

    /**
     * How to write a text file with Java 7:
     *
     * 
    {@code try (BufferedWriter writer = Files.newBufferedWriter(path)) {
     *  writer.write(text);
     *}}
    */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在 Java SE 18 中,引入了@snippet标签,可以用于代码片段的注释

    /**
     * How to write a text file with Java 7:
     *
     * {@snippet :
     * try (BufferedWriter writer = Files.newBufferedWriter(path)) {
     *   writer.write(text);
     * }
     * }
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    更多

    Java SE 7及以后各版本新增特性

    参考资料

    JDK 18 Release Notes

    Java18 新特性

    New Features in Java 18

    Java 18 Features (with Examples)

  • 相关阅读:
    51单片机定时炸弹-准确计时-两根线随机一根触发中断可“拆弹“(AT89C52)
    欲知己之所防,先知彼之所攻——论Hook 技术的攻防对抗
    解析前端最想了解的全栈开发
    看完这篇,还不懂JAVA内存模型(JMM)算我输
    ubuntu安装freeradius3, freeradius3-mysql并配置
    vue修饰符的用法
    【echarts 】设置datazoom 允许使用鼠标滚轮滚动图表
    微软宣布 Windows 11 开始大范围推送
    测试/开发程序员的“我“要跳槽,利与弊共存......
    类与对象(三)
  • 原文地址:https://blog.csdn.net/hotonyhui/article/details/126464010