从 Java 8 迁移到 Java 17 (二):Java 中值得注意的 API 变化
这是上一篇文章的续篇:
从第 8 版到第 17 版,Java 经历了巨大的演变,实现了多种增强和新的生活质量改进。本文将深入探讨 Java 后续版本中引入的 API 变化和新增功能,我认为这些变化和新增功能对于从 Java 8 迁移到 Java 17 的用户来说最为有趣和有用。
Java 9
Java 9 引入了模块系统,标志着 Java 生态系统发生了重大变革,但同时也带来了一些有价值的 API 增强功能:
Objects.requireNonNullElse
该方法有助于简化对空值的处理,无需进行冗长的空值检查。
Java 8:
String value = (str != null) ? str : "default";
Java 9 :
String value = Objects.requireNonNullElse(str, "default");
Collection 工厂方法
Java 9 中引入了创建不可变 collections 的便捷工厂方法。
Java 8:
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
List<String> unmodifiableList = Collections.unmodifiableList(list);
Java 9 :
List<String> list = List.of("a", "b", "c");
增强型流(Stream) API
为流 API 添加了 takeWhile()
、dropWhile()
和带谓词的 iterate()
等方法,以便对流进行更多函数式操作。
Java 9 :
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> result = numbers.stream()
.takeWhile(n -> n < 4)
.collect(Collectors.toList());
CompletableFuture.delayedExecutor()
引入该功能是为了方便安排有延迟的任务。
Java 9 :
Executor executor = CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS);
Collectors.flatMapping()
方便在收集器内进行平面映射操作,这对复杂的还原非常有用。
Java 9 :
List<List<String>> listOfLists = List.of(List.of("a", "b"), List.of("c", "d"));
List<String> flattenedList = listOfLists.stream()
.collect(Collectors.flatMapping(List::stream, Collectors.toList()));
增强型 Optional
ifPresentOrElse() 等新方法提高了 Optional
类的可用性和灵活性。
Java 9 :
Optional<String> optional = Optional.of("Hello");
optional.ifPresentOrElse(
value -> System.out.println("Value: " + value),
() -> System.out.println("No value present")
);
java.util.concurrent.Flow
为支持反应流而引入。
Java 9 :
import java.util.concurrent.Flow;
Java 10
Java 10 延续了渐进式改进的趋势,更加注重性能和可用性的调整:
局部变量类型推断(var)
var
关键字虽然不是 API 的改动,但它允许更简洁的变量声明并提高了可读性。
Java 10 :
var list = new ArrayList<Map<String, List<Integer>>>();
不可修改的 Collections
引入了 List.copyOf()
、Set.copyOf()
和 Map.copyOf()
等方法,用于创建不可修改的集合副本。
Java 8:
List<String> list = new ArrayList<>();
list.add("a");
List<String> unmodifiableList = Collections.unmodifiableList(list);
Java 10 :
List<String> list = List.copyOf(originalList);
Optional 增强
添加了不带参数的 orElseThrow()
方法。
Java 10 :
Optional<String> optional = Optional.empty();
String value = optional.orElseThrow(); // Throws NoSuchElementException
Java 11
Java 11 带来了几个值得注意的 API 增强功能,特别是在String
操作和InputStream
处理方面:
String 增强
String
类增加了 repeat(int)
方法,可轻松重复字符串。
Java 8:
String repeated = String.join("", Collections.nCopies(3, "abc"))
Java 11 :
String repeated = "abc".repeat(3);
InputStream 增强
引入了 readNBytes(int)
,以便更有控制地从 InputStream
读取字节。
Java 8:
byte[] buffer = new byte[10];
int bytesRead = inputStream.read(buffer, 0, 10);
Java 11 :
byte[] buffer = inputStream.readNBytes(10);
新 Files 方法
添加了 writeString()
和 readString()
方法,以简化文件 I/O 操作。
Java 8:
Files.write(Paths.get("file.txt"), "Hello, World!".getBytes(StandardCharsets.UTF_8));
String content = new String(Files.readAllBytes(Paths.get("file.txt")), StandardCharsets.UTF_8);
Java 11 :
Files.writeString(Path.of("file.txt"), "Hello, World!", StandardCharsets.UTF_8);
String content = Files.readString(Path.of("file.txt"), StandardCharsets.UTF_8);
Java 12
单文件源代码程序
可直接运行单个 Java 源文件,简化了小型快速脚本和测试的流程。
Java 8:
javac HelloWorld.java
java HelloWorld
Java 12 :
java HelloWorld.java
Switch 表达式(预览)
为 switch 语句引入了多大小写标签,现在这些语句也可以直接返回值,从而无需单独的赋值语句。
Java 12 Example (Preview):
int numLetters = switch (day) {
case "MONDAY", "FRIDAY", "SUNDAY":
yield 6;
case "TUESDAY":
yield 7;
case "THURSDAY", "SATURDAY":
yield 8;
case "WEDNESDAY":
yield 9;
default:
throw new IllegalArgumentException("Unexpected day: " + day);
};
Java 14
Switch 表达式 (标准功能)
switch
语句的新箭头语法使流程更加简洁,不再需要穿透语义。该功能在 Java 14 中成为标准功能。
Java 8:
int numLetters;
switch (day) {
case "MONDAY":
case "FRIDAY":
case "SUNDAY":
numLetters = 6;
break;
case "TUESDAY":
numLetters = 7;
break;
case "THURSDAY":
case "SATURDAY":
numLetters = 8;
break;
case "WEDNESDAY":
numLetters = 9;
break;
default:
throw new IllegalArgumentException("Unexpected day: " + day);
}
Java 14 :
int numLetters = switch (day) {
case "MONDAY", "FRIDAY", "SUNDAY" -> 6;
case "TUESDAY" -> 7;
case "THURSDAY", "SATURDAY" -> 8;
case "WEDNESDAY" -> 9;
default -> throw new IllegalArgumentException("Unexpected day: " + day);
};
Java 15
文本块
正式从预览版毕业,为处理多行字符串提供了一种简洁的方法。
Java 15 :
String sqlQuery = """
SELECT id, name, age
FROM users
WHERE age > 30
ORDER BY age DESC
""";
字符串格式化方法
引入 String::formatted
方法是为了获得更好的字符串格式化能力。
Java 8:
String formatted = String.format("Name: %s, Age: %d", name, age);
Java 15 :
String formatted = "Name: %s, Age: %d".formatted(name, age);
Java 16
Records
引入 record 类,以减少创建简单数据载体类时的模板。
Java 8:
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override
public boolean equals(Object o) {
// equality logic
}
@Override
public int hashCode() {
// hashcode logic
}
@Override
public String toString() {
// toString logic
}
}
Java 16 :
public record Person(String name, int age) {}
针对 instanceof
的模式匹配
通过为 instanceof
引入模式匹配,简化了构建。
Java 8:
if (obj instanceof String) {
String str = (String) obj;
// Use str
}
Java 16 :
if (obj instanceof String str) {
// Use str directly
}
Stream.toList()
添加了一种方便的方法,可将流元素直接收集到不可修改的列表中。
Java 8:
List<String> list = stream.collect(Collectors.toList());//mutable
Java 16 :
List<String> list = stream.toList(); //unmodifiable
Java 17
十六进制二进制数据表示
Java 17 提供了以十六进制形式表示二进制数据的实用程序,这对调试非常有用
Java 17 :
byte[] data = new byte[] { 0x1A, 0x2B, 0x3C };
String hex = HexFormat.of().formatHex(data);
System.out.println(hex); // Outputs: 1a2b3c
ZoneId.ofOffset()
已添加 ZoneId.ofOffset()
,可直接从偏移量创建区域 ID。
Java 8:
ZoneId zone = ZoneId.of("UTC+01:00");
Java 17 :
ZoneId zone = ZoneId.ofOffset("UTC", ZoneOffset.ofHours(1));
你也许感兴趣的:
- 【外评】不要把 Rust 写成 Java
- “甲骨文牌”Java正在死亡
- 您现在可以像运行 Python 一样运行 Java
- 从 Java 8 迁移到 Java 17:新功能大汇总
- Oracle 再夺 Java 命?大公司用 Java 要小心了!
- 【程序员搞笑图片】java haters
- Java 22 新功能特性及示例
- Java 22 中最令人兴奋的 3 个功能
- 【译文】Java 21 – Kotlin 是否正在消亡?
- 【译文】Java 22 的速度有多快?
你对本文的反应是: