Java SE 18 新增特性

作者:Grey

原文地址: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);

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

方案二:通过系统属性 "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);
}
}

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

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

运行结果如下

?????????????????????????????????

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

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

运行结果如下

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

在 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("你好");
}
}

输出结果为:

Default charset : UTF-8
file.encoding : UTF-8
native.encoding : GBK
UTF-8
你好

JDK 自带 Web Server

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Java自带的WebServer</title>
</head>
<body>
Web Server By JDK18
</body>
</html>

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

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

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

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/

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

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

如果我们想把多行代码片段集成到 JavaDoc 中,我们必须通过<pre>...</pre>来完成,而且必须与{@code ...}相结合,这样做非常麻烦

下面是一个使用<pre>标签的例子:

/**
* How to write a text file with Java 7:
*
* <pre>{@code try (BufferedWriter writer = Files.newBufferedWriter(path)) {
* writer.write(text);
*}}</pre>
*/

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

/**
* How to write a text file with Java 7:
*
* {@snippet :
* try (BufferedWriter writer = Files.newBufferedWriter(path)) {
* writer.write(text);
* }
* }
*/

更多

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

参考资料

JDK 18 Release Notes

Java18 新特性

New Features in Java 18

Java 18 Features (with Examples)

最新文章

  1. jsp内置对象浅谈
  2. 带优先级的队列 - PHP实现
  3. Windows下将程序打包为安装包(最为简易的方式)
  4. 2015年10个最佳Web开发JavaScript库
  5. [转]jQuery,javascript获得网页的高度和宽度
  6. BZOJ1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富
  7. HC-MAC: A Hardware-Constrained Cognitive MAC for Efficient Spectrum Management
  8. android如何调用显示和隐藏系统默认的输入法(一)
  9. HTML DOM的nodeName,nodeValue,nodeType介绍
  10. 整理Ruby相关的各种概念(rvm, gem, bundle, rake, rails等)
  11. Java8 lamda表达式快速上手
  12. 声明数组变量/// 计算所有元素的总和/打印所有元素总和/输出/foreach循环/数组作为函数的参数/调用printArray方法打印
  13. 别人的Linux私房菜(15)磁盘配额与高级文件系统管理
  14. Spring cache 使用说明
  15. python爬虫之Anaconda安装
  16. Spring Security Filter执行顺序
  17. qhfl-5 redis 简单操作
  18. Eclipse布局问题小记
  19. nodemcu使用心得1
  20. win10虚拟桌面;一不小心按错了突然只剩下桌面,启动的程序都没了

热门文章

  1. C# 类继承中的私有字段都去了哪里?
  2. GDKOI 2021 Day3 PJ 懵逼记
  3. mysql5.7安装要踩的坑
  4. 论文阅读 Exploring Temporal Information for Dynamic Network Embedding
  5. 数据库 OLAP、OLTP是什么?相同和不同?适用场景
  6. android stdio开发抖音自动点赞案例
  7. 关于cpu体系架构的一些有趣的故事分享
  8. protobuf 的交叉编译使用(C++)
  9. Springboot 启动初始化bin,InitializingBean
  10. 【干货】MySQL底层架构设计,你了解多少?