JDK新特性汇总(jdk8~17)
本篇文章将会为大家介绍 JDK 8 — JDK 17 的新增的一些特性,帮助我们更好地理解和使用Java编程语言。
1 JDK8
1.1 Lambda表达式
Lambda表达式是JDK 8中最重要的新特性之一,它是一种简洁的语法,用于创建函数式接口的实例。Lambda表达式可以作为一种更简洁、更灵活的替代匿名内部类的形式。Lambda表达式语法如下:
(parameter1, parameter2, ...) -> { body }
示例代码:
List<String> list = Arrays.asList("Java", "Scala", "C++", "Python", "Ruby");
// 使用Lambda表达式过滤和打印列表
list.stream()
.filter(s -> s.startsWith("J"))
.forEach(System.out::println);
1.2 方法引用
方法引用是一种更简单的Lambda表达式语法,用于调用现有方法作为Lambda表达式的实现。可以通过使用操作符“::”访问方法。方法引用可以使代码更加简洁、易于阅读和重构。
示例代码:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Lambda表达式
numbers.stream()
.map(n -> n * n)
.forEach(n -> System.out.print(n + " "));
// 改为方法引用的形式
numbers.stream()
.map(n -> n * n)
.forEach(System.out::print);
1.3. 接口默认方法
接口默认方法允许将方法实现添加到接口中,而不会破坏现有的类和接口的实现。这些方法会默认提供实现,但是也可以在接口的实现中被覆盖。
示例代码:
interface HelloWorld {
default void sayHello() {
System.out.println("Hello, World!");
}
}
class HelloWorldImpl implements HelloWorld {
// sayHello方法在HelloWorld接口中有默认实现
}
HelloWorld helloWorld = new HelloWorldImpl();
helloWorld.sayHello(); // 输出"Hello, World!"
1.4 Stream API
Stream API提供了一种简单、高效、并行处理集合元素的方式。它可以处理大量数据,提高代码可读性并提高应用程序的性能。
示例代码:
List<String> list = Arrays.asList("Java", "Scala", "C++", "Python", "Ruby");
// 使用Stream API过滤和打印列表
list.stream()
.filter(s -> s.startsWith("J"))
.forEach(System.out::println);
1.5 日期和时间API
Java 8引入了一个新的日期和时间API,它包括了许多用于处理日期和时间的类,可以使日期和时间的操作更加易于理解和更加安全。
示例代码:
// 日期时间API
LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间: " + now);
LocalDateTime christmas = LocalDateTime.of(2021, Month.DECEMBER, 25, 0, 0);
System.out.println("圣诞节时间: " + christmas);
1.6 Optional类
Optional类提供了一种更好地处理Null或缺失值的方式。当代码中有Null引用时,Optional类提供了一种更好地方式,避免了Null引用异常。
示例代码:
// 使用Optional类来避免Null引用异常
Optional<String> str = Optional.ofNullable(null);
if (str.isPresent()) {
System.out.println(str.get());
} else {
System.out.println("没有值!");
}
1.7 Nashorn JavaScript引擎
Nashorn JavaScript引擎是JDK 8中的另一个特性,它是一种新的JavaScript引擎,可以直接在Java代码中执行JavaScript代码,从而使Java和JavaScript之间的交互变得更加方便。
示例代码:
// 使用Nashorn JavaScript引擎执行JavaScript代码
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
Object result = engine.eval("var greeting='Hello'; greeting + ', World!'");
System.out.println(result); // 输出 "Hello, World!"
1.8 Base64编码
JDK 8中引入了Base64类,用于将数据转换为Base64编码。Base64编码非常常用,特别是在网络编程中。
示例代码:
// 使用Base64类进行编码和解码
String text = "java8-additional-features";
byte[] base64EncodedBytes = Base64.getEncoder().encode(text.getBytes());
System.out.println("Base 64 编码: " + new String(base64EncodedBytes));
byte[] base64DecodedBytes = Base64.getDecoder().decode(base64EncodedBytes);
System.out.println("解码后的数据: " + new String(base64DecodedBytes));
1.9 总结:
以上是JDK 8中的8个新特性,涉及语言增强、新的库和工具等。这些新特性提高了Java程序的效率、可读性和安全性,使得Java编程变得更加方便和灵活。了解这些特性,有助于开发更优秀的Java应用程序。
2 JDK 9
2.1 模块化系统
JDK 9 中最重要的特性是模块化系统,它可以更好地组织代码并管理依赖项。模块可以指定自己的依赖项,并只向外部暴露需要的 API。这样,应用程序可以在编译时对这些声明的依赖项进行检查,以检测潜在的问题。
以下是一个示例模块:
module com.example.mymodule {
requires java.logging; // 模块依赖于 java.logging
exports com.example.mypackage; // 暴露 com.example.mypackage 包
}
2.2 JShell
JDK 9 中引入了 JShell,这是一个基于命令行的 REPL(Read Eval Print Loop),它允许开发者在执行代码之前即时预览和测试代码。使用 JShell,我们可以轻松地对 Java 代码进行实验和学习,而不需要编写整个程序或运行渲染器。
以下是一个简单的 JShell 示例:
jshell> int x = 5
x ==> 5
jshell> int y = 7
y ==> 7
jshell> x + y
$3 ==> 12
2.3 HTTP/2 客户端
JDK 9 中现在引入了一个基于 HTTP/2 的 HTTP 客户端 API,可以更好的处理并发请求和响应。这个 API 支持异步和同步调用,并且可以在请求过程中进行流控制。
以下是一个 HTTP/2 客户端的例子:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://www.example.com"))
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
2.4 优化的 Javadoc
JDK 9 中改进了 Javadoc 工具,可以让文档更加易读和友好。它现在支持 HTML5 输出,增强了搜索和导航功能,并提供了更好的支持注释。
2.5 集合工厂
JDK 9 中引入了一个新的集合工厂 API,用于轻松创建不可变的集合。这些集合不可变,并且支持快速可靠的操作。
以下是使用集合工厂创建不可变列表的示例:
List<String> list = List.of("foo", "bar", "baz");
2.6 改进的 Streams API
在 JDK 9 中,Streams API 得到了改进,以更好地支持操作无限/未知大小的流和合并两个流。
以下是一个源自未知大小的流的示例:
Stream.generate(() -> new Random().nextInt())
.limit(10)
.forEach(System.out::println);
2.7 进程 API
JDK 9 中引入了一组新的进程 API,用于将 Java 应用程序和操作系统进程进行交互。这些功能可以帮助我们创建并检查进程,以及管理控制台 I/O 和信号处理。
以下是一个创建和启动进程的示例:
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
Process process = builder.start();
int exitCode = process.waitFor();
System.out.println("Process exited with code " + exitCode);
2.8 改进的 try-with-resources 语句
JDK 9 中改进了 try-with-resources 语句,可以让我们更轻松地管理资源,并避免繁琐的 try-catch-finally 块。
以下是一个使用 try-with-resources 处理流的示例:
try (InputStream in = new FileInputStream("input.txt");
OutputStream out = new FileOutputStream("output.txt")) {
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
2.9 拓展 Unicode 支持
JDK 9 中增强了对 Unicode 支持,增加了 9000 多个字符,包括 Emoji 和其他符号。此外,还引入了一个新的 API,用于将 Unicode 文本转换为首字母大写或小写的形式。
以下是一个使用新的 Unicode 转换 API 的示例:
String input = "HÉLLO, WǑRLD!";
String capitalized = CaseMapper.toTitleCase(input, Locale.ENGLISH);
System.out.println(capitalized);
2.10 对象私有接口方法
JDK 9 中,Java 接口可以包含私有的方法。这些方法可以帮助我们封装实现细节,并防止接口的实现者错误地暴露这些细节。
以下是一个使用私有接口方法的例子:
public interface MyInterface {
default void process() {
doProcess();
}
private void doProcess() {
// 私有方法实现
}
}
2.11 总结:
JDK 9 引入了许多新特性,包括模块化系统、JShell、HTTP/2 客户端、优化的 Javadoc、集合工厂、改进的 Streams API、进程 API、改进的 try-with-resources 语句、拓展 Unicode 支持、对象私有接口方法。这些功能可以帮助 Java 开发者更加轻松、高效地编写代码。
3 JDK 10
3.1 局部变量类型推断
JDK 10支持局部变量类型推断,这意味着可以不需要在声明变量时显式声明数据类型。此特性使得代码更加简洁、易读。
示例代码:
var a = "Hello, World!"; // 推断出a的类型是String
3.2 Application Class-Data Sharing
JDK 10增加了Application class-data sharing(AppCDS)功能。AppCDS可以在启动时共享类元数据,从而加快JVM的启动速度。
示例代码:
java -Xshare:dump # 将类元数据打包成共享归档文件
java -Xshare:on # 使用共享归档文件启动JVM
3.3 线程局部握手机制
JDK 10改进了线程局部握手机制,从而提高了并发性能。新的实现使用了跟踪和对象分配原语,降低了延迟。
示例代码:
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("Hello, World!");
String value = threadLocal.get(); // 获取线程局部变量
3.4 增强了Optional类
JDK 10增强了Optional类,允许使用orElseThrow()方法抛出指定的异常。这使得代码更加简洁、易读。
示例代码:
Optional<String> optional = Optional.ofNullable(null);
String value = optional.orElseThrow(IllegalArgumentException::new);
3.5 增强的接口
JDK 10增强了接口,可以在接口中声明私有方法和私有静态方法。这更好地支持类库的演化。
示例代码:
public interface MyInterface {
default void myMethod() {
myPrivateMethod();
}
private void myPrivateMethod() {
System.out.println("This is a private method.");
}
private static void myPrivateStaticMethod() {
System.out.println("This is a private static method.");
}
}
3.6 HTTP Client
JDK 10提供了新的HTTP Client API,可以使用HTTP/2协议进行异步请求。这使得Java程序可以更容易地与Web Services通信。
示例代码:
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
3.7 总结:
JDK 10增加了很多新特性和改进,包括局部变量类型推断、Application Class-Data Sharing、线程局部握手机制、增强的Optional类、增强的接口和HTTP Client。这些改进使得Java开发更加简单、高效,也展示了Java生态系统的强大。
4 JDK 11
4.1 HTTP Client
JDK 11继续增强了HTTP Client API,支持WebSocket和HTTP的长轮询。WebSocket可以支持双向通信,而长轮询可以在没有数据时保持连接直到有新的数据。
示例代码:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.header("Connection", "Upgrade")
.header("Upgrade", "websocket")
.GET()
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
4.2 增强的Lambda表达式
JDK 11增强了Lambda表达式,支持局部变量语法。这意味着不需要显式声明类型,可以根据上下文进行推断。此外,也支持到处使用var关键字。
示例代码:
(var x, var y) -> x + y // 使用var推导lambda参数
4.3 紧凑型堆
JDK 11引入了紧凑型堆(ZGC),是一个实验性特性。ZGC支持将Java堆大小限制在几百兆字节的范围内,以便更快地处理大型堆。
示例代码:
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx256m MyApp
4.3 增强的垃圾回收器
JDK 11增强了G1垃圾回收器,引入了一个新的干扰线程,以便更高效地使用CPU和内存。
示例代码:
java -XX:+UseG1GC -XX:G1HeapRegionSize=16M MyApp
4.4 Epsilon GC
JDK 11引入了Epsilon GC,它是一个实验性的无操作垃圾回收器。当您需要运行短期的测试时,可以使用Epsilon GC,以便更快地完成测试过程。
示例代码:
java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC MyApp
4.5 var在Lambda表达式中的使用
JDK 11允许在Lambda表达式中使用var关键字,使代码更加简洁、易读。
示例代码:
(BinaryOperator<Integer>) (var a, var b) -> a + b
4.6 总结:
JDK 11增加了很多新特性和改进,包括增强的HTTP Client、增强的Lambda表达式、紧凑型堆、增强的垃圾回收器和Epsilon GC。这些改进使得Java开发更加简单、高效,也展示了Java生态系统的强大。
5 JDK 12
JDK 12是Java开发工具包的最新版本,于2019年3月19日发布。此版本包含了一些新功能和改进,提供了更好的性能、安全性和更好的功能。
5.1 Shenandoah垃圾收集器
JDK 12引入了一个新的垃圾收集器,Shenandoah GC。 Shenandoah GC 是一种低暂停时间的垃圾收集器,它减少了 Java 应用程序的 GC 时间,从而提高了 JVM 的总体性能表现。
Shenandoah GC 使用了一些新的垃圾收集技术,包括Concurrent Cycle, Load Reference Barrier, concurrent evacuation和 concurrent class unloading等,这些技术能够减少垃圾收集器的暂停时间,提高了应用程序的性能和稳定性。
示例代码:
java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC MyApp
5.2 JEP 189: 基于协程的轻量级Fiber
JDK 12引入了一种新的机制,称为基于协程的轻量级Fiber。它可以更有效地支持无限数量的轻量级线程,从而提高性能。
在Java中,Thread(线程)是一种很重的并发处理机制,在大部分情况下,线程可能会导致资源的封锁和耗费CPU,这些都在轻量级线程的Fiber中得到了解决。
此外,Fiber 还具有以下优点:
- 更低的资源开销
- 比线程更高效
- 更短的执行时间
- 更好的扩展性
示例代码:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
CompletionStage<Integer> stage = future.thenApplyAsync(s -> s.length() * 2);
stage.thenAccept(System.out::println);
5.3 JEP 325: Switch Expressions
Java 12引入了一种新的switch表达式。这允许开发人员更清晰地编写代码,避免常见的重复代码,并可以在编写更复杂的控制结构时提供更大的灵活性。
Switch Expressions 具有以下优点:
- 更简洁的代码
- 支持多种表达式
- 更好的类型查询
示例代码:
String result = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Weekday";
case SATURDAY, SUNDAY -> "Weekend";
default -> "Invalid day";
};
5.4 JEP 334: JVM中的响应式流
JDK 12支持在Java虚拟机中自动管理的响应式流。这使得在处理大型数据集时更容易编写高性能的、反应能力强的数据流应用程序。
响应式流提供了以下特性:
- 反应性
- 异步性
- 分布式
- 高可靠性
示例代码:
Flowable.just("Hello world").subscribe(System.out::println);
5.5 JEP 340: 使用 CDS 建立默认类列表
JDK 12引入了一种基于类数据共享(CDS)的新特性,将时常使用的类数据全部建立为映像文件,通过启动器可以在相对较短的时间内加载大量必要的JDK项,从而增加性能。
JEP 340称为应用程序类数据共享,主要设计和实现基于OpenJDK,将已经被JDK加载的一些常用类型,通过特定的映像文件在启动时实现快速预计算,可以很快地映射到JVM运行时,加速JDK类库的加载过程。
示例代码:
java -Xshare:on -Xlog:class+path MyApp
5.6 总结:
JDK 12带来了Shenandoah垃圾收集器、基于协程的轻量级Fiber、Switch Expressions、JVM中的响应式流和使用CDS建立的默认类列表等新特性。这些特性使开发者能够更轻松地编写高性能、响应能力强的应用程序。它们使得Java的生态系统更加强大,同时也提高了性能和安全性。
6 JDK 13
6.1 ZGC:低暂停时间垃圾回收器
JDK 13 中引入了一种名为 ZGC 的新型垃圾回收器,它是一种并行、可插拔和可伸缩的 GC 实现。ZGC 旨在减少长时间暂停的时间,使大型应用程序在仍保持高性能的情况下运行更长时间。以下是一些示例代码:
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
6.2 完全支持 Unicode 12.1
JDK 13 支持 Unicode 12.1 版本,它包含了超过 137,000 个字符。这意味着 Java 可以更容易处理日本、韩国等的字符集。以下是一些示例代码:
String text = "\uD83D\uDE00"; // 表情符号Unicode编码
System.out.println(text);
6.3 Switch 表达式改进
JDK 13 的 switch 表达式现在支持箭头语法,这使得代码更加简洁和易于阅读。
int x = 2;
int result = switch (x) {
case 1 -> 5;
case 2 -> 10;
default -> 15;
};
System.out.println(result); // 输出 10
6.4 Text Blocks
Text Blocks 是一种更直观的多行字符串语法。使用三个双引号扩起来,而不是自己手动添加转义字符 \n。
String text = """
我们在这里,
留下美好的回忆,
再见了!
""";
System.out.println(text);
6.5 Shenandoah GC
除了 ZGC,JDK 13 还引入了另外一个垃圾回收器 Shenandoah GC。Shenandoah GC 主要针对大内存的应用程序,并且在执行期间不会发生停顿。
-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
6.6 动态 CDS 归档
在 JDK 13 中引入了动态 Class-Data Sharing(CDS)归档,它使得开发者可以在运行时为特定应用程序创建自定义存档。
java -Xshare:dump
java -Xshare:on
6.7 安全 HTTP 客户端
JDK 13 中的 HTTP 客户端现在支持更安全的加密套件。它还包括了错误代码的处理方式,从而使开发者能够更好地了解错误原因。
HttpClient client = HttpClient.newBuilder()
.sslContext(SSLContext.getDefault())
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
6.8 结论:
JDK 13 提供了许多强大的新特性,包括了垃圾回收器、Unicode 支持、Text Blocks、switch 表达式改进、动态 CDS 归档等。这些特性为软件开发人员提供了更多的选择和工具,以帮助他们创建更好的 Java 程序。
7 JDK 14
7.1. Records
JDK 14 中引入了 Records,Records 是一种新的 Java 类型。它们旨在提高代码的可读性和简洁性,将一些 Java Bean 需要的方法自动化为一组常规用例的简单组合。以下是示例代码:
public record Person(String name, int age) { }
Person john = new Person("John", 30);
System.out.println(john.name()); // 输出 "John"
7.2. Pattern Matching for instanceof
JDK 14 中的 instanceof 表达式现在可以使用模式匹配,这使得代码更加简洁并且更容易理解。
if (obj instanceof String s && s.length() > 0) {
System.out.println(s.charAt(0));
}
7.3. 允许调用同类中的私有方法
在 JDK 14 中,允许在同一类中调用其他私有方法。这可以使代码更加模块化,逻辑比较清晰。
public class Main {
private void method1() {
System.out.println("method1");
}
private void method2() {
method1();
}
public static void main(String[] args) {
Main main = new Main();
main.method2(); // 输出 "method1"
}
}
7.4. Switch 表达式增强
在 JDK 14 中,Switch 表达式增加了新的 yield 关键字,使得代码更加简洁。
String type = "FIRST";
int numLetters = switch (type) {
case "FIRST" -> {
yield 5;
}
case "SECOND" -> {
yield 6;
}
default -> {
yield 7;
}
};
System.out.println(numLetters); // 输出 5
7.5. NullPointerException 异常详细信息增强
在 JDK 14 中,NullPointerException 异常的详细信息中将包括引起异常的变量的名称和原因。
例如,下面的代码将引发一个 NPE 异常:
Integer x = null;
int y = x + 1;
在 JDK 14 中,出现 NPE 异常时,将给出以下详细信息:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "<local1>" is null
at Main.main(Main.java:9)
7.6. Records Serialization
在 JDK 14 中,Records 类型支持序列化,并且可以使用默认的序列化机制或自定义序列化机制。以下是示例代码:
public record Person(String name, int age) implements Serializable { }
Person john = new Person("John", 30);
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.ser"));
oos.writeObject(john);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
7.7. 句柄(Class File Version 58)
在 JDK 14 中,引入了句柄(Class File Version 58),它是一种新的 Java 字节码文件格式。它将有助于编译器和虚拟机针对封装类型等进行更好的优化。
7.8 结论:
JDK 14 提供了许多强大的新特性,包括了 Records、模式匹配、Switch 表达式增强、NullPointerException 异常详细信息增强等。这些特性为软件开发人员提供了更多的选择和工具,以帮助他们创建更好的 Java 程序。
8 JDK 15
8.1. 私有接口方法
在 JDK 15 中,我们可以在接口中声明私有方法。私有方法可以在接口的默认方法和静态方法中共享,从而避免重复代码的问题。以下是示例代码:
public interface MyInterface {
default void foo() {
bar();
}
private void bar() {
System.out.println("do something...");
}
}
8.2. ZGC 增强
在 JDK 15 中,ZGC(一种低延迟垃圾回收器)得到了许多增强,包括了在已经占用的堆空间上执行垃圾回收,以及增加柔性的引用处理等。
8.3. 隐式的向构造函数传递参数
在 JDK 15 中,可以使用新的 var 关键字来传递隐式参数到构造函数中。以下是示例代码:
public class Person {
public Person(String name, int age) {
// do something
}
}
var john = new Person("John", 30);
8.4. Text Blocks
在 JDK 15 中,Text Blocks 是一种新的字符串类型,旨在简化多行字符串拼接。这种字符串类型使用三重引号(“““)来表示,并且可以嵌入换行符和变量。
String html = """
<html>
<body>
<p>Hello, world!</p>
<p>Today's date is ${new Date()}</p>
</body>
</html>
""";
8.5. GC 日志信息增强
在 JDK 15 中,增强了 GC 日志信息,可以更好地监控应用程序的内存使用情况。现在,GC 日志可以包括容器的详细信息、日志文件轮换等。
8.6. Unix 套接字的可选 Multiplexing
在 JDK 15 中,Unix 套接字支持可选 Multiplexing。这意味着在单个套接字上可以同时处理多个客户端请求的连续读取、写入或检测。这有助于提高性能和可扩展性。
8.7. Record 类型增强
JDK 15 中继续增强了 Record 类型,现在可以使用属性的推导类型来简化代码,同时还有一些其他可选项。
以下是示例代码:
public record Person(String name, int age) {
public Person {
if (age < 0 || age > 120)
throw new IllegalArgumentException("Invalid age: " + age);
}
}
8.8. 简化的类和接口的默认修饰符
在 JDK 15 中,简化了类和接口的默认修饰符。现在,如果没有指定访问修饰符,那么类和接口将默认为包私有的。
8.9. 结论:
JDK 15 在功能和改进上都有所增加。在这篇文章中,我们详细介绍了 JDK 15 的新特性,包括了私有接口方法、ZGC 增强、隐式的向构造函数传递参数、Text Blocks、GC 日志信息增强、Unix 套接字的可选 Multiplexing、Record 类型增强、简化的类和接口的默认修饰符和移除无用的 JVM 选项,这些功能和改进将有助于提高 Java 程序的性能和可扩展性。
9 JDK 16
9.1 静态代码块的改进
在 JDK 16 中,静态代码块的执行顺序被改进。在过去,如果存在多个静态代码块,它们的执行顺序是按照它们在代码中定义的顺序来决定。在 JDK 16 中,静态代码块的执行顺序将按照它们在 bytecode 中的出现顺序来决定。
以下示例为一个简单的类,其中包含两个静态代码块:
public class StaticBlockExample {
static {
System.out.println("Static block 1");
}
public static void main(String[] args) {
System.out.println("Main method");
}
static {
System.out.println("Static block 2");
}
}
在 JDK 16 下运行该程序的输出如下:
Static block 1
Static block 2
Main method
9.2 类型模式匹配的改进
在 JDK 16 中,类型模式匹配语法得到了改进。类型模式匹配语法是在 JDK 14 中引入的,用于简化实例类型检查的代码,如下所示:
if (obj instanceof String s) {
System.out.println(s.length());
}
在 JDK 16 中,类型模式匹配语法支持添加条件语句,用于更加灵活地完成类型检查。以下示例代码演示了如何使用类型模式匹配语法和条件语句:
public class InstanceOfExample {
public static void main(String[] args) {
Object obj = "hello world";
if (obj instanceof String s && s.length() > 0) {
System.out.println(s.length());
}
}
}
该程序输出 11
。
9.3 JEP 396:弃用Java EE 和 CORBA 模块
在 JDK 16 中,Java EE 和 CORBA 相关的模块被弃用。Java EE 和 CORBA 是过去 Java 平台上广受欢迎的技术栈和协议,但现在已经不再适用,因此相应的模块在 JDK 16 中被弃用。如需使用这些模块,可以考虑在第三方库中进行引用。
9.4 JEP 394:模式匹配(实例of)类型升级
在 JDK 16 中,类型模式匹配的最新升级版本引入了一个新的 operator,可以更加简洁地判断实例类型是否在给定的类层级中。以下示例演示了如何使用新的 operator(instanceof):
public class InstanceOfExample {
public static void main(String[] args) {
Object obj = "hello world";
if (obj instanceof String s) {
System.out.println(s.length());
}
// 新的 operator
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
}
}
9.5 JEP 393:垃圾收集器(ZGC)的改进
ZGC 是 JDK 11 中引入的内存管理技术,它能够大大缩短垃圾回收的时间,同时也在 JDK 16 中得到更多的改进。以下是 JDK 16 中 ZGC 的改进:
- 通过增加 Load barriers 以及更好的空间压缩技术,ZGC 在 Java 虚拟机中的垃圾回收和对象更新操作的开销得到了大幅度的优化。
- ZGC 方案现在支持异步堆转储。
- 随着垃圾回收器记忆组件的不断优化,ZGC 方案的性能和可扩展性得到了大幅度的提升。
9.6 JEP 338:默认的 CDS 归档
在 JDK 16 中,默认情况下启用了 CDS(Class Data Sharing)归档文件。CDS 会将类元数据和字节码预处理并存储在归档文件中,以加快应用程序的启动速度和内存效率。默认启用 CDS 归档文件将有助于缩短 Java 应用程序的代码加载时间,并减少 JVM 的内存占用。可以通过设置启动选项 -XX:-UseCDS 来禁用 CDS 归档文件功能。
9.7 总结:
JDK 16 带来了很多新特性和改进,包括静态代码块执行顺序改进、类型模式匹配的新 operator、弃用 Java EE 和 CORBA 相关模块、ZGC 方案的新优化、默认启用 CDS 归档文件等。这些新特性和改进将有助于优化 Java 应用程序的性能和效率,提高 Java 平台的使用体验。
好的,下面进行修改和补充,让文章更加详尽。
10 JDK 17
10.1. 移除实验性功能
在 JDK 17 中,已经移除了一些实验性功能。这些实验性功能包括:
- java.applet 模块:Java Applet 是一种基于浏览器的 Java 程序,现在已经不受欢迎。
- javah 命令:javah 用于生成 JNI 接口文件,现在已有更好的工具替代。
- jcmd、jhat、jmap、jstack、jstat 命令:这些命令现在已经被 jhsdb 命令替代。
- -Xverify:none 选项:该选项现在已弃用,建议使用其他选项。
10.2. 改进垃圾回收器
在 JDK 17 中,对 G1 垃圾收集器进行了改进,以提高其性能和可靠性。具体来说,G1 垃圾回收器现在通过使用堆上对象引用信息而不是安全点信息来确定 root 表,这可以提高 G1 垃圾回收器在多处理器系统上的扩展性。这一改进可以帮助用 G1 收集器运行大型、并发程序的用户获得更好的性能。
此外,JDK 17 还引入了一个新的垃圾回收器,称为 ZGC。这种垃圾回收器可以更快地处理大型内存分配,且无需暂停时间。这是一种用于大型堆的低延迟 GC 技术,目的是避免在生产环境下出现严重的垃圾收集停顿。该回收器侧重于在非常大的堆上执行一些主要 GC 暂停。以下是一个使用 ZGC 垃圾回收器的示例代码:
-Xmx16g -Xms16g -XX:+UseZGC
10.3. Pattern Matching for switch
JDK 17 引入了新的语言特性,可以为 switch 语句增加模式匹配。这项新特性可以简化针对特定类型的语句处理。模式匹配允许 switch 语句匹配常量、类型、枚举、class 等。具体来说,Pattern Matching 可以和 instanceof 运算符一起使用,用于检查对象是否属于某个类或其子类或实现了某个接口。以下是一个模式匹配的示例代码:
public int getPoints(Object obj) {
return switch (obj) {
case "red" -> 10;
case "yellow" -> 5;
case String s && s.startsWith("green") -> 3;
case Integer i && i > 0 -> i;
default -> 0;
};
}
10.4. Sealed 类和接口
JDK 17 中还引入了一个新的类和接口修饰符,称为 Sealed。这使得程序员可以更好地限制哪些类或接口可以扩展或实现另一个类或接口。Sealed 类和接口的限制可以帮助开发人员在应用程序中实现更好的封装和继承控制。以下是一个使用 Sealed 类和接口的示例代码:
public sealed class Shape permits Circle, Rectangle, Triangle {
//...
}
final class Circle extends Shape {
//...
}
final class Rectangle extends Shape {
//...
}
final class Triangle extends Shape {
//...
}
10.5. 基于 JEP423 的 System.setProperty 的限制
在 JDK 17 中,加入了对 System.setProperty 的一些限制,以降低代码中的滥用。现在,对于一些关键的系统属性,必须具有特定的权限才能修改。这将有助于提高安全性,并防止不必要的代码更改。
10.6. JFR 事件流
JDK 17 还增强了 Java Flight Recorder(JFR)的功能。现在,可以在应用程序中捕获和分析 JFR 事件流,以更好地了解应用程序的性能和行为。以下是一个使用 JFR 事件流的示例代码:
JfrEvent event = new JfrEvent("jdk.ExecutionSample", Instant.now());
event.begin();
try {
//... your application code ...
} finally {
event.end();
}
10.7 总结:
JDK 17 中的新功能和改进集中在提高性能、安全性和健壮性方面。它引入了一些新的语言特性,增强了垃圾回收器、JFR,并提高了系统安全性。对于 Java 开发人员来说,这些新特性提供了更多的工具和选项来创建更高效、更可靠和更安全的应用程序。