UTF-8作为默认字符集
在Java 18中,UTF-8被指定为标准Java API的默认字符集。这个变化使得依赖于默认字符集的API在所有实现、操作系统、区域设置和配置上保持一致。
这个变化的主要目标有:
- 提高可预测性和可移植性:当代码依赖于默认字符集时,Java程序更加可预测和可移植。
- 明确标准Java API使用默认字符集的地方:UTF-8在标准Java API中得到了标准化,除了控制台I/O之外的所有地方都使用UTF-8。
- 不是定义新的标准Java API:这个变化的目标不是定义新的标准Java API或支持的JDK API。尽管这项工作可能会发现使现有API更易于使用的新的便利方法,但不打算废弃或删除依赖于默认字符集的标准Java API。
在读写文件和操作文本方面,标准Java API允许将字符集作为参数传递。字符集控制了Java编程语言的原始字节与16位字符值之间的转换。例如,支持的字符集包括US-ASCII、UTF-8和ISO-8859-1。如果没有传递字符集参数,标准Java API通常会使用默认字符集。JDK在启动时根据运行时环境(操作系统、用户区域设置等)选择默认字符集。然而,因为默认字符集在不同地方不同,使用默认字符集的API存在一些不明显的危险,即使对经验丰富的开发人员也是如此。
考虑一个应用程序创建了一个没有传递字符集的java.io.FileWriter ,然后使用它将一些文本写入文件。生成的文件将包含使用运行应用程序的JDK的默认字符集编码的字节序列。另一个在不同机器上运行的应用程序,或者在同一机器上由不同用户运行的应用程序,创建了一个没有传递字符集的java.io.FileReader ,并使用它读取该文件的字节。生成的文本包含使用第二个应用程序运行的JDK的默认字符集解码的字符序列。如果第一个应用程序的JDK和第二个应用程序的JDK之间的默认字符集不同,生成的文本可能会损坏或不完整,因为FileReader 无法知道它使用了FileWriter的错误字符集进行解码。这种情况下,使用UTF-8作为默认字符集可以避免这类问题。
因此,Java 18的这一变化对于提高Java程序的可靠性和可移植性非常有益。
简易Web服务器
Java 18引入了一个名为**Simple Web Server**的工具,它是一个最小化的HTTP静态文件服务器,被添加到了**jdk.httpserver**模块中(JEP 408)。这个工具的目的是为了在原型制作、临时编码和测试等场景下提供便利,而不是用于生产环境。让我们来了解一下这个简易Web服务器的特点和使用方法。
- 功能和用途:
- Simple Web Server仅支持**HEAD**和**GET**请求方法。
- 它只能服务于一个单一的目录层次结构。
- 服务器仅提供静态文件,不支持动态内容或其他HTTP版本。
- 这个工具的目标是让开发人员能够快速上手,专注于任务本身,而不必担心复杂的配置和功能。
- 命令行工具:
- 使用提供的命令行工具启动服务器是最简单的方法。
- 使用`jwebserver`命令即可启动服务器。默认情况下,它会绑定到回环地址(127.0.0.1)和端口8000,并服务于当前工作目录。
- 例如,运行以下命令启动服务器:
java$ jwebserver
- 如果启动成功,服务器将在前台运行,并在System.out中打印本地地址和正在服务的目录的绝对路径。
- 自定义设置 :
可以使用以下选项来自定义服务器的行为:
- `-b`或`--bind-address`:指定绑定的地址,默认为回环地址。
- `-p`或`--port`:指定监听的端口,默认为8000。
- `-d`或`--directory`:指定要服务的目录,默认为当前目录。
- `-o`或`--output`:指定输出格式,默认为info。
- `-version`或`--version`:显示Simple Web Server的版本信息。
4.使用场景:
- Simple Web Server适用于原型制作、临时编码和测试等场景。
- 如果您需要更丰富的功能或用于生产环境的服务器,可以考虑其他选项,如Apache Tomcat或Jetty。
这个简易Web服务器的设计理念是简单、易用,让开发者能够快速开始Web开发,而不必花费过多精力在配置和复杂性上。
Java API文档中的代码片段
Java 18引入了一个新特性------Java API文档中的代码片段 ,以更方便地将示例源代码嵌入API文档中。这个特性通过**@snippet** 标签实现,它取代了之前的**@code**标签,并具有更强大的功能。让我们一起看看如何在Java 18的文档中使用这个新标签。
1. 在行内添加代码片段
使用**@snippet**标签,我们可以在Javadoc注释中直接插入代码片段。以下是如何在行内添加代码片段的示例:
java/** * The code below shows the content of {@code helloBaeldung()} method * {@snippet : * public void helloBaeldung() { * System.out.println("Hello From Team Baeldung"); * } * } */ public class GreetingsInlineSnippet { public void helloBaeldung() { System.out.println("Hello From Team Baeldung"); } }
在上面的示例中,我们在文档中添加了helloBaeldung() 方法。首先,我们定义了**@snippet**标签,然后在标签内部编写代码片段。
2. 添加外部代码片段
除了行内代码片段,我们还可以从外部文件或类中添加代码片段。首先,我们需要使用**@start** 和**@end**标签指定要添加的代码区域。例如,下面是一个展示如何在Java中实现二分查找的简单文档:
javapublic class BinarySearch { public int search(int[] list, int item) { int index = Integer.MAX_VALUE; int low = 0; int high = list.length - 1; // @start region="binary" while (low <= high) { int mid = high - low; int guess = list[mid]; if (guess == item) { index = mid; break; } else if (guess > item) { low = mid - 1; } else { low = mid + 1; } low++; } // @end region="binary" return index; } }
在上面的代码中,我们使用了**@start** 和**@end**标签来指定要添加到文档的代码区域。这样,我们可以在文档中展示二分查找的实现细节。
总之,Java 18的**@snippet**标签使得在API文档中添加代码片段变得更加简单和灵活。
向量API
Java 18的向量API是一个孵化特性,它允许开发者表达向量计算,这些计算在运行时可靠地编译为支持的CPU架构上的最优向量指令,从而实现比等效标量计算更优越的性能。这个API的主要目标是:
- 清晰简洁的API:能够清晰且简洁地表达一系列向量操作组成的向量计算,这些计算可能包含在循环中,并可能伴有控制流。
- 平台无关性:API应该是CPU架构无关的,使得在多种架构上实现支持向量指令的可能性。在平台优化和可移植性之间存在冲突时,API倾向于保持可移植性,即使这意味着某些特定于平台的习惯用法可能无法在可移植代码中表达。
- 在x64和AArch64架构上的可靠运行时编译和性能:在支持向量指令的x64架构上,Java运行时(特别是HotSpot C2编译器)应将向量操作编译为相应的高效且性能优异的向量指令。开发者应该有信心,他们表达的向量操作将可靠地映射到相关的向量指令上。在支持向量指令的ARM AArch64架构上,C2也将类似地将向量操作编译为NEON和SVE支持的向量指令。
- 优雅降级:有时,向量计算无法在运行时完全表达为一系列向量指令,可能是因为架构不支持某些所需的指令。在这种情况下,向量API实现应该优雅地降级并继续运行。如果向量计算无法有效地编译为向量指令,可能会发出警告。
向量API通过提供一种方式来编写复杂的向量算法,使用现有的HotSpot自动向量化器,但用户模型使向量化更加可预测和稳健。简而言之,向量API旨在通过同时对多个数据片段执行简单操作(例如加法),而不是传统的一次处理一个数据片段的方式,来提高计算性能。