JDK9-21新特性概览
- 一、JDK9 新特性
-
- 1.1 JEP 102: Process API Updates
- 1.2 JEP 193: Variable Handles
- 1.3 JEP 200: The Modular JDK
- 1.4 JEP 213: Milling Project Coin
- 1.5 JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
- 1.6 JEP 254: Compact Strings
- 1.7 JEP 248: Make G1 the Default Garbage Collector
- 1.8 JEP 264: Platform Logging API and Service
- 1.9 JEP 270: Reserved Stack Areas for Critical Sections
- 1.10 JEP 269: Convenience Factory Methods for Collections
- 1.11 JEP 271: Unified GC Logging
- 1.12 JEP 280: Indify String Concatenation
- 1.13 JEP 285: Spin-Wait Hints
- 其他
- 二、JDK10 新特性
- 三、JDK11 新特性
-
- 3.1 JEP 181: Nest-Based Access Control
- 3.2 JEP 309: Dynamic Class-File Constants
- 3.3 JEP 318: Epsilon: A No-Op Garbage Collector (Experimental)
- 3.4 JEP 321: HTTP Client
- 3.5 JEP 323: Local-Variable Syntax for Lambda Parameters
- 3.6 JEP 330: Launch Single-File Source-Code Programs
- 3.7 JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
- 四、JDK12 新特性
- 五、JDK13 新特性
- 六、JDK14 新特性
-
- 6.1 JEP 305: Pattern Matching for instanceof (Preview)
- 6.2 JEP 345: NUMA-Aware Memory Allocation for G1
- 6.3 JEP 349: JFR Event Streaming
- 6.4 JEP 352: Non-Volatile Mapped Byte Buffers
- 6.5 JEP 358: Helpful NullPointerExceptions
- 6.6 JEP 359: Records (Preview)
- 6.7 JEP 361: Switch Expressions
- 6.8 JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector
- 6.9 JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination
- 6.10 JEP 368: Text Blocks (Second Preview)
- 七、JDK15 新特性
-
- 7.1 JEP 360: Sealed Classes (Preview)
- 7.2 JEP 371: Hidden Classes
- 7.3 JEP 374: Deprecate and Disable Biased Locking
- 7.4 JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (Production)
- 7.5 JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector (Production)
- 7.6 JEP 378: Text Blocks
- 7.7 JEP 384: Records (Second Preview)
- 八、 JDK16 新特性
- 九、 JDK17 新特性
-
- 9.1 Restore Always-Strict Floating-Point Semantics
- 9.2 Enhanced Pseudo-Random Number Generators
- 9.3 New macOS Rendering Pipeline
- 9.4 macOS/AArch64 Port
- 9.5 Deprecate the Applet API for Removal
- 9.6 Strongly Encapsulate JDK Internals
- 9.7 Pattern Matching for switch (Preview)
- 9.8 Remove RMI Activation
- 9.9 Sealed Classes
- 9.9 Remove the Experimental AOT and JIT Compiler
- 9.10 Deprecate the Security Manager for Removal
- 9.11 Foreign Function & Memory API (Incubator)
- 9.12 Vector API (Second Incubator)
- 9.13 Context-Specific Deserialization Filters
一、JDK9 新特性
1.1 JEP 102: Process API Updates
简介
该提议旨在改进 Java 程序对操作系统进程管理的支持,主要通过对 java.lang.Process 和 java.lang.ProcessHandle 增强,方便更好管控操作系统进程资源。
案例
ProcessHandle currentProcess = ProcessHandle.current();
long currentPid = currentProcess.pid();
ProcessHandle.Info info = currentProcess.info();
System.out.printf("Current Process PID: %d%n", currentPid);
info.command().ifPresent(cmd -> System.out.printf("Command: %s%n", cmd));
info.startInstant().ifPresent(start -> System.out.printf("Start time: %s%n", start));
info.totalCpuDuration().ifPresent(cpu -> System.out.printf("CPU usage: %s%n", cpu));
// 获取并管理当前进程的所有子进程
currentProcess.children().forEach(child -> {
System.out.printf("Child PID: %d%n", child.pid());
child.destroy(); // 销毁子进程
// 监听当前进程的状态变化
child.onExit().thenRun(() -> System.out.println("Process has exited"));
});
风险
跨平台的时候,需要考虑不同操作系统的差异。
1.2 JEP 193: Variable Handles
简介
变量句柄(Variable Handles)是对Java内存模型进行的一次重要增强。变量句柄是对Java中的变量进行更灵活和高效访问的机制,主要是方便对一个类中的变量进行细粒度的管控,类似于安全的反射,具有更高的性能和类型安全。它们提供了一组方法来读取和写入变量,并且可以原子地操作这些变量。
变量句柄提供了一种统一的方式来访问各种类型的变量,包括字段、数组元素和静态变量。它们在并发编程中尤为有用,因为它们支持高级的同步操作和内存屏障。
由单个抽象类java.lang.invoke.VarHandle、java.lang.invoke.MethodHandles实现,VarHandle中包含了不同的访问模式,是多态的一种体现。
- 读访问模式,读最新的变量值
- 写访问模式,对变量的更新对其他线程可见
- 原子更新访问模式
- 数字原子更新访问模式,例如getAndAdd。
- 位原子更新访问模式,如getAndbitwise
案例
public class VariableHandleExample {
// 声明实例字段和静态变量句柄
private int x;
private static VarHandle X_HANDLE;
// 声明数组和数组元素句柄
private final int[] array = new int[10];
private static VarHandle ARRAY_HANDLE;
static {
try {
// 初始化实例字段的变量句柄
X_HANDLE = MethodHandles.lookup ().findVarHandle (VariableHandleExample.class, "x", int.class);
// 初始化数组元素的变量句柄
ARRAY_HANDLE = MethodHandles.arrayElementVarHandle(int[].class);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace ();
}
}
// 使用变量句柄获取实例字段x的值
public int getX() {
return (int) X_HANDLE.get(this);
}
// 使用变量句柄设置实例字段x的值
public void setX(int value) {
X_HANDLE.set(this, value);
}
// 使用变量句柄进行实例字段x的原子比较并交换操作
public boolean compareAndSetX(int expected, int newValue) {
return X_HANDLE.compareAndSet(this, expected, newValue);
}
// 使用变量句柄获取数组元素的值
public int getElement(int index) {
return (int) ARRAY_HANDLE.get(array, index);
}
// 使用变量句柄设置数组元素的值
public void setElement(int index, int value) {
ARRAY_HANDLE.set(array, index, value);
}
public static void main(String[] args) {
VariableHandleExample example = new VariableHandleExample();
// 设置和获取实例字段x的值
example.setX(42);
System.out.println("Value of x: " + example.getX()); // 输出:Value of x: 42
// 原子比较并交换操作
boolean updated = example.compareAndSetX(42, 100);
System.out.println("Updated: " + updated); // 输出:Updated: true
System.out.println("Value of x: " + example.getX()); // 输出:Value of x: 100
// 设置和获取数组元素的值
example.setElement(0, 123);
System.out.println("Value at index 0: " + example.getElement(0)); // 输出:Value at index 0: 123
}
}
风险
性能还需要更多的验证。
1.3 JEP 200: The Modular JDK
简介
将JDK划分为一组模块,这些模块可以在编译时、构建时和运行时组合成各种配置,更易于提高安全性和可维护性,提高应用程序性能,并为开发人员提供更好的大型编程工具。
整个流程大致分为三步:
- 使用moudule-info.java来声明一个模块,一个模块只能有一个文件,且在顶层包同目录下
- 使用exports来声明可以被外部引用的包可以有多个exports语句
- 使用requires来声明依赖的外部的模块可以有多个requires语句
案例
module 被引用模块 {
// 导出的子模块
exports com.nju.jdk9;
}
module 引用模块{
// 引用的子模块
requires jdk9;
}
风险
有些用例不能支持,还存在一些缺陷,留待后续迭代的时候进行完善。
1.4 JEP 213: Milling Project Coin
简介
主要是对语言的细微改进来提高Java的可读性和可维护性。
try-with-resources使用的简化- 允许接口中私有方法,只能在该接口内部使用,主要用于重用代码,减少重复。
案例
1.4.1 try-with-resources增强
import java.io.*;
public class TryWithResourcesExample {
public static void main(String[] args) throws IOException {
// 在 try 块外部声明和初始化资源
Reader reader = new BufferedReader(new FileReader("test.txt"));
try (reader) {
// 使用资源
System.out.println(reader.read());
}
}
}
1.4.2 接口中私有方法
interface MyInterface {
default void doSomething() {
sayHello ();
sayGoodBye();
}
void sayGoodBye();
private void sayHello() {
System.out.println ("hello");
}
}
public class PrivateInterfaceImpl implements MyInterface{
public static void main(String[] args) {
PrivateInterfaceImpl impl = new PrivateInterfaceImpl ();
impl.doSomething ();
}
@Override
public void sayGoodBye() {
System.out.println ("bye");
}
}
1.5 JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
新增JShell控制台进行交互编程(就跟python一样,直接控制台编码,输出)
1.6 JEP 254: Compact Strings
之前的JDK版本采用char数组存储字符串,char默认两个字节存储,JDK9采用byte数组更加节约存储空间
1.7 JEP 248: Make G1 the Default Garbage Collector
使用G1作为默认的垃圾收集器,减少GC期间STW(Stop the World)的时间,以提供更好的用户体验。
1.8 JEP 264: Platform Logging API and Service
提供了更轻量级的默认的日志APIjava.util.logging。
1.9 JEP 270: Reserved Stack Areas for Critical Sections
简介
给线程栈预留了更多的空间,减少并发情况下StackOverflow风险,避免进一步的并发问题,如死锁。
当一个临界区由几个方法组成时,例如一个方法a调用了一个方法b,可用的堆栈足以让方法a执行。方法a开始修改数据结构,然后调用方法b,但是剩余的堆栈不足以执行b,导致StackOverflowError。因为方法b和方法a的剩余部分没有执行,所以数据结构的一致性可能已经受到损害。
案例
// 无法保证原子操作
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
1.10 JEP 269: Convenience Factory Methods for Collections
简介
通过工厂方法,用于创建不可变的集合实例。这些方法通过java.util.List, java.util.Set, 和 java.util.Map接口中的静态方法实现,使得创建集合对象的语法更加简洁、清晰。
案例
public class CollectionsExample {
public static void main(String[] args) {
// 使用List.of()创建不可变的列表
List<String> list = List.of("one", "two", "three");
System.out.println("List: " + list); // 输出: List: [one, two, three]
// 尝试修改列表会抛出UnsupportedOperationException
// list.add("four"); // 这行代码会抛出异常
// 使用Set.of()创建不可变的集合
Set<String> set = Set.of("one", "two", "three");
System.out.println("Set: " + set); // 输出: Set: [one, two, three]
// 尝试修改集合会抛出UnsupportedOperationException
// set.add("four"); // 这行代码会抛出异常
// 使用Map.of()创建不可变的映射
Map<String, Integer> map = Map.of("one", 1, "two", 2, "three", 3);
System.out.println("Map: " + map); // 输出: Map: {one=1, two=2, three=3}
// 使用Map.ofEntries()创建不可变的映射
Map<String, Integer> mapEntries = Map.ofEntries(
Map.entry("one", 1),
Map.entry("two", 2),
Map.entry("three", 3)
);
System.out.println("Map with Entries: " + mapEntries); // 输出: Map with Entries: {one=1, two=2, three=3}
// 尝试修改映射会抛出UnsupportedOperationException
// map.put("four", 4); // 这行代码会抛出异常
}
}
1.11 JEP 271: Unified GC Logging
提供统一的GC日志API。log_info(gc, heap, ergo)("Heap expanded"); 通过GC tag的来控制打印哪些内容。
1.12 JEP 280: Indify String Concatenation
简介
旨在通过使用invokedynamic(java.lang.invoke.StringConcatFactory)指令来优化字符串连接操作。这种方法使用invokedynamic指令,并将连接逻辑推迟到运行时,以便可以更好地利用JVM的优化能力。
在Java 9之前,字符串连接通常是通过StringBuilder的隐式使用来实现的。
案例
String m(String a, int b) {
return a + "(" + b + ")";
}
其中JDK8编译上述代码后:
JDK9编译上述代码后:

优点
- 性能优化:通过将字符串连接推迟到运行时,JVM可以应用更高效的优化策略。
- 减少内存开销:避免了大量的StringBuilder对象的创建和销毁,降低了GC压力。
- 灵活性:运行时优化允许JVM根据具体情况选择最佳的连接策略,适应不同的硬件和JVM实现。
1.13 JEP 285: Spin-Wait Hints
简介
引入了“旋转等待提示”(Spin-Wait Hints),即在多线程编程中提供一种机制,通过标准化的方法向底层处理器传达线程处于“自旋等待”(spin-wait)的状态,在 java.lang.Thread.onSpinWait() 中实现自旋等待提示。
案例
public class SpinWaitExample {
private volatile boolean condition = false;
public void waitForCondition() {
while(!condition) {
Thread.onSpinWait ();
}
System.out.println ("Condition change to true");
}
public void setCondition() {
condition = true;
}
public static void main(String[] args) throws InterruptedException {
SpinWaitExample example = new SpinWaitExample ();
Thread waiter = new Thread (example::waitForCondition);
waiter.start ();
Thread.sleep (1000);
example.setCondition ();
waiter.join ();
}
}
优点
- 提高性能:自旋等待提示允许处理器优化资源利用和功耗管理,在高性能计算场景中特别有用。
- 降低延迟:适用于需要低延迟同步的场景,例如高频交易系统或实时处理系统。
- 标准化:提供了一个标准API,避免了使用特定于平台的低级指令,提高了代码的可移植性。
其他
InputStream增强
新增了transferTo方法,可以用来将数据直接传输到 OutputStream
Stream API的增强
public class StreamApiExample {
public static void main(String[] args) {
testForTakeWhile();
testForDropWhile();
testForOfNullable();
testForIterate();
}
// takeWhile用于从 Stream 中获取一部分数据,接收一个 Predicate 来选择从开头开始的满足条件的元素。
public static void testForTakeWhile(){
List<Integer> list = Arrays.asList(10,20,30,40,30</

最低0.47元/天 解锁文章
752

被折叠的 条评论
为什么被折叠?



