JDK9-21新特性概览(持续更新)

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.1 try-with-resources增强
        • 1.2 接口中私有方法
    • 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
      • 简介
      • 案例
    • 2.0 JEP 269: Convenience Factory Methods for Collections
      • 简介
      • 案例
    • 2.1 JEP 271: Unified GC Logging
    • 2.2 JEP 280: Indify String Concatenation
      • 简介
      • 案例
      • 优点
    • 2.3 JEP 285: Spin-Wait Hints
      • 简介
      • 案例
      • 优点
    • 其他
      • InputStream增强
      • Stream API的增强
  • 二、 JDK11 新特性(TODO)
  • 三、JDK13新特性(TODO)
  • 四、JDK15新特性(TODO)

一、JDK9新特性

1.1 JEP 102: Process API Updates

简介

该提议旨在改进 Java 程序对操作系统进程管理的支持,主要通过对 java.lang.Processjava.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.VarHandlejava.lang.invoke.MethodHandles实现,VarHandle中包含了不同的访问模式,是多态的一种体现。

  1. 读访问模式,读最新的变量值
  2. 写访问模式,对变量的更新对其他线程可见
  3. 原子更新访问模式
  4. 数字原子更新访问模式,例如getAndAdd。
  5. 位原子更新访问模式,如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: trueSystem.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划分为一组模块,这些模块可以在编译时、构建时和运行时组合成各种配置,更易于提高安全性和可维护性,提高应用程序性能,并为开发人员提供更好的大型编程工具。

整个流程大致分为三步:

  1. 使用moudule-info.java来声明一个模块,一个模块只能有一个文件,且在顶层包同目录下
  2. 使用exports来声明可以被外部引用的包可以有多个exports语句
  3. 使用requires来声明依赖的外部的模块可以有多个requires语句

案例

module 被引用模块 {// 导出的子模块exports com.nju.jdk9;
}module 引用模块{// 引用的子模块requires jdk9;
}

风险

有些用例不能支持,还存在一些缺陷,留待后续迭代的时候进行完善。

1.4 JEP 213: Milling Project Coin

简介

主要是对语言的细微改进来提高Java的可读性和可维护性。

  1. try-with-resources使用的简化
  2. 允许接口中私有方法,只能在该接口内部使用,主要用于重用代码,减少重复。

案例

1.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.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 ();}@Overridepublic 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());elseacquire(1);
}

2.0 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); // 这行代码会抛出异常}
}

2.1 JEP 271: Unified GC Logging

提供统一的GC日志API。log_info(gc, heap, ergo)("Heap expanded"); 通过GC tag的来控制打印哪些内容。

2.2 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编译上述代码后:JDK8编译
JDK9编译上述代码后:
在这里插入图片描述

优点

  • 性能优化:通过将字符串连接推迟到运行时,JVM可以应用更高效的优化策略。
  • 减少内存开销:避免了大量的StringBuilder对象的创建和销毁,降低了GC压力。
  • 灵活性:运行时优化允许JVM根据具体情况选择最佳的连接策略,适应不同的硬件和JVM实现。

2.3 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,20,10);list.stream().takeWhile(t->t<40).forEach(t -> System.out.print(t + " "));System.out.println ();List<Integer> list2 = Arrays.asList(1,2,3,4,5,6,7);list2.stream().takeWhile(t->t<7).forEach(t -> System.out.print(t + " "));System.out.println ();}// dropWhile 的行为与 takeWhile 相反,返回剩余的元素public static void testForDropWhile() {List<Integer> list = Arrays.asList(10,20,30,40,30,20,10);list.stream().dropWhile(t->t<40).forEach(t-> System.out.print(t + " "));System.out.println ();List<Integer> list2 = Arrays.asList(1,2,3,4,5,6,7);list2.stream().dropWhile(t->t<7).forEach(t -> System.out.print(t + " "));System.out.println ();}// ofNullable 方法允许我们创建一个Stream,可以所有元素均为空。public static void testForOfNullable() {// JDK8允许通过Stream<String> streams = Stream.of("AA","BB",null);System.out.println(streams.count());// JDK8不允许通过/*Stream<Object> stream2 = Stream.of(null);System.out.println(stream2.count());*/// JDK9允许通过Stream<Object> stream2 = Stream.ofNullable(null);System.out.println(stream2.count());}// iterate 可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。public static void testForIterate() {// 原始方式Stream.iterate(1,i->i+1).limit(50).forEach(t -> System.out.print(t + " "));System.out.println ();// 增强方式Stream.iterate(1,i->i<60,i->i+1).forEach(t -> System.out.print(t + " "));}
}

二、 JDK11 新特性(TODO)

三、JDK13新特性(TODO)

四、JDK15新特性(TODO)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot实现接口防抖的几种方案,杜绝重复提交

插&#xff1a; AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

RK3568平台(camera篇)V4L2查询获取设置设备

一.查询设备能力VIDIOC_QUERYCAP struct v4l2_capability cap; ioctl(fd, VIDIOC_QUERYCAP, &cap) struct v4l2_capability 结构体描述了视频采集设备的 driver 信息。 struct v4l2_capability { __u8 driver[16]; // 驱动名字 __u8 card[32]; // 设备名字 __u8 bus_inf…

详解makefile中的foreach

在 Makefile 中&#xff0c;foreach 函数用于迭代处理一个以空格分隔的列表&#xff0c;并针对列表中的每个元素执行相同的操作。这个函数通常用于循环处理一组变量或文件名&#xff0c;并执行相同的规则或命令。 语法&#xff1a; makefile Copy Code $(foreach var, list, …

ThingsBoard物联网网关在智慧城市数据采集中的应用

智慧城市由监控中心、采集网关、前端采集设备、前端感应执行器组成。 为何选用ThingsBoard作为平台 监控中心为物联网平台&#xff0c;该平台包含云计算、大数据、人工智能、物联网、GIS、云安全等主要模块&#xff0c;具备数据采集、数据交换、超大规模计算、数据分析、数据应…

防火墙如何端口映射?

防火墙端口映射&#xff08;Firewall Port Mapping&#xff09;是一种网络技术&#xff0c;通过对防火墙配置进行调整&#xff0c;允许外部网络用户访问内部网络中的指定端口。该技术使得外部用户可以通过公共网络访问内部网络中的特定服务或应用程序&#xff0c;从而实现远程访…

JavaScript--作用域是什么

作用域是什么 编译原理 在传统的编译语言中&#xff0c;程序中的一段源代码在执行之前会经历三个步骤。成为编译 分词/词法分析 这个过程由字符组成的字符串分解成有意义的代码块&#xff0c;这些代码块成为词法单元。 分词和词法分析之间的主要差异在于词法单元的识别是有…

实战指南:Vue 2基座 + Vue 3 + Vite + TypeScript微前端架构实现动态菜单与登录共享

实战指南&#xff1a;Vue 2基座 Vue 3 Vite TypeScript子应用vue2微前端架构实现动态菜单与登录共享 导读&#xff1a; 在当今的前端开发中&#xff0c;微前端架构已经成为了一种流行的架构模式。本文将介绍如何结合Vue 2基座、Vue 3子应用、Vite构建工具和TypeScript语言…

基于Docker的ROS开发

本文主要介绍如何使用Docker在Windows和Linux环境中部署并使用ROS&#xff0c;通过Docker Container运行ROS&#xff0c;可以方便我们在一个本地环境中运行多个ROS版本。 更多内容&#xff0c;访问专栏目录获取实时更新。 关于ROS的版本 参考ROS1 Distribution Wiki和ROS2 Dis…

nginx源码阅读理解 [持续更新,建议关注]

文章目录 前述一、nginx 进程模型基本流程二、源码里的小点1.对字符串操作都进行了原生实现2.配置文件解析也是原生实现待续 前述 通过对 nginx 的了解和代码简单阅读&#xff0c;发现这个C代码的中间件确实存在过人之处&#xff0c;使用场景特别多&#xff0c;插件模块很丰富…

10款AI工具,让工作生活学习更高效

我看大家都推荐的差不多了&#xff0c;常见好用的PC软件就那些&#xff0c;我不想反复“咀嚼”了&#xff0c;我想另辟蹊径推荐点不一样的&#xff0c;比如10款PC端的AI网站。AI已经全方位“侵入”我们的生活&#xff0c;从AI写作到AI绘画&#xff0c;从AI视频到AI语音&#xf…

Thingsboard规则链:Switch节点详解

在物联网&#xff08;IoT&#xff09;领域&#xff0c;数据的高效处理与自动化决策是构建智能系统的核心。作为一款强大的物联网平台&#xff0c;Thingsboard通过其规则引擎为开发者提供了高度灵活的工具&#xff0c;其中Switch节点是实现消息条件路由的关键组件。本文将全方位…

【深度学习】Transformer梳理

零、前言 对于transformer&#xff0c;网上的教程使用记号、术语不一 。 最关键的一点&#xff0c;网上各种图的简化程度不一 &#xff08;画个图怎么能这么偷懒&#xff09; &#xff0c;所以我打算自己手画一次图。 看到的最和善&#xff08;但是不是那么靠谱&#xff0c;我…

黑龙江某市数字孪生地下水监测系统平台项目建设经验

项目背景 地下水是一种特殊而珍贵的资源&#xff0c;它具有不可替代性&#xff0c;与经济发展及人民生活息息相关&#xff0c;针对日趋严峻的水资源危机&#xff0c;如何合理利用有限的水资源&#xff0c;保障国民经济的可持续发展是一个迫切需要解决的问题。 黑龙江某市积极…

eclipse启动时间过长的问题

项目场景&#xff1a; 由于我用eclipse比较习惯&#xff0c;虽然IDEA很好&#xff0c;但是因为收费&#xff0c;所以在个人开发学习过程中一直还是使用eclipse&#xff0c;本文不讨论eclipse与IDEA孰优孰劣问题。 开发环境&#xff1a; 操作系统&#xff1a;Windows 11 22631…

【小呆的力学笔记】连续介质力学的知识点回顾一:运动和变形

文章目录 1. 运动的描述2. 拉格朗日描述下的变形2.1 线元的变化2.2 体元的变化2.3 面元的变化 1. 运动的描述 在连续介质力学中&#xff0c;存在着两种对运动的描述&#xff0c;一种为拉格朗日描述&#xff0c;即通过描述每个物质点的运动来描述整个变形体的运动&#xff0c;也…

如何将音频中的人声分离出来?

想要把一段视频中的人声跟背景音乐分离开来&#xff0c;找个好一点的音频处理软件就能把声音分离了&#xff0c;常见的有以下方法&#xff0c;一起来看看吧。 pr 打开软件&#xff0c;然后将电脑上的音频文件&#xff0c;上传到软件中&#xff0c;然后按住[ctrla]选择所有音频…

【数据结构】 排序算法 ~ 总结篇

文章目录 1. 排序几个重点概念的理解2. 排序算法的分析&#x1f427; 1. 排序几个重点概念的理解 2. 排序算法的分析&#x1f427;

Git学习篇

目录 使用命令导入项目 使用命令导入项目 1. 使用git init 命令初始化一个新的Git仓库。 git init 是 Git 命令&#xff0c;用于初始化一个新的 Git 仓库。当您想要开始跟踪一个新项目的版本控制时&#xff0c;可以运行 git init 命令来初始化一个空的 Git 仓库。 如果出现以下…

6-继承

6-继承 1、基本语法和方式2、继承的基本特点2.1 三种继承方式相同的基本点2.2 三种继承方式的差别2.3 公有继承的独有特点 3、子类的构造、析构3.1 子类的构造3.2 子类的析构3.3 子类的拷贝构造函数3.4 子类的拷贝赋值 4、多重继承4.1 内存布局4.2 类型转换4.3 名字冲突问题 5、…

10. C++异步IO处理库和使用libevent实现高性能服务器

C比较有名的异步IO处理库 libevent 这个主要使用的是epoll。libevthplibuvlibev 我们主要介绍libevent。 libevent重要函数 event_base_new 这个可以对应于epoll_create也就是创建一个实例。还可以初始化libevent所有管理相关的代码。比如说所能用到的队列&#xff0c;栈&a…