JDK 8 (2014年发布, LTS版本)
- Lambda表达式: 引入了函数式编程能力,允许更简洁地表示匿名函数。
- Stream API: 提供了强大的数据处理管道,支持函数式操作如map、filter、reduce等。
- 接口的默认方法与静态方法: 允许在接口中定义默认实现和静态方法。
- 方法引用: 一种更简洁的引用已有方法的方式。
- Optional类: 用于避免空指针异常,提供更优雅的空值处理方式。
- 新的日期/时间API:
java.time包,提供了更易于使用的日期和时间类。
JDK 9 (2017年发布)
- 模块系统 (Jigsaw) : 引入模块化,提高大型应用的可维护性和性能。
- JShell: 交互式Java命令行工具,可以直接运行代码片段。
- 改进的Javadoc: 支持HTML5,更好的文档体验。
- 私有接口方法: 接口可以有私有方法。
- G1成为默认垃圾收集器:替代了Parallel Scavenge+Parallel Old组合,提升垃圾收集效率。
JDK 10 (2018年发布)
- 局部变量类型推断 (var关键字) : 类似于C#的var,简化代码编写。
- 垃圾收集器接口: 为不同GC实现提供统一接口。
- 并行全垃圾收集: G1优化,提升G1垃圾收集器的并行性。
JDK 11 (2018年发布, LTS版本)
- Flight Recorder: 强大的监控和诊断工具,原为商业特性,现免费开放。
- HTTP客户端API (HttpClient) : 标准化的HTTP客户端API。
- 字符串增强: 更高效的字符串处理,增加了一些实用的API,如isBlank()、strip()、stripLeading()、stripTrailing()等方法。。
- ZGC和Epsilon GC: 新的垃圾收集器,分别针对低延迟和极简配置。
JDK 12至16 (2019年至2021年发布)
这些版本中引入了多个实验性特性,部分在后续版本中成为正式特性,包括但不限于:
-
Switch Expressions
-
引入版本: 正式引入是在JDK 14,并在JDK 17中作为稳定特性存在。
-
如何使用: Switch Expressions 允许switch语句作为表达式使用,意味着它可以返回一个值。这使得代码更加简洁,特别是在需要根据不同的条件返回不同结果的场景。从JDK 14开始,还可以使用yield语句来指定每个case块的返回值。例如:
int day = 2; String dayOfWeek = switch (day) { case 1 -> "Monday"; case 2 -> "Tuesday"; default -> "Invalid Day"; }; System.out.println(dayOfWeek);
-
-
Text Blocks
-
引入版本: 正式引入是在JDK 15,并在JDK 17中成为稳定特性。
-
如何使用: Text Blocks允许你创建多行字符串,无需使用转义字符。这对于编写HTML、SQL等格式化文本特别有用。你可以通过三重引号(
""")来定义文本块,并且可以自动管理换行和缩进。例如:String html = """ <html> <body> <p>Hello, world!</p> </body> </html> """;
-
-
Pattern Matching for instanceof
-
引入版本: 正式引入是在JDK 16,并在JDK 17中成为稳定特性。
-
如何使用: 此特性简化了类型检查和转换的语法。使用
instanceof关键字后可以直接绑定到一个变量,无需再做显式的类型转换。例如:Object obj = getObject(); if (obj instanceof String str) {// 如果obj是期望的类型(在这里是String),则此变量会被自动赋予转换后的对象引用,无需再单独进行类型转换 System.out.println("The string is: " + str.toLowerCase()); }
-
-
Shenandoah GC
- 引入版本: 最初在JDK 12作为实验特性出现,逐步成熟并在后续版本中得到优化,但具体作为稳定特性被广泛推荐使用的版本可能因具体JDK版本而异。
- 如何使用: Shenandoah是一种低暂停时间垃圾收集器,旨在减少GC暂停对应用程序的影响。要使用它,你可以在启动Java应用时通过JVM参数
-XX:+UseShenandoahGC启用。
-
Record
-
引入版本: 正式引入是在JDK 14,并在JDK 17中成为稳定特性。
-
如何使用: Record简化了不可变数据类的定义,自动生成构造器、getter方法、equals()、hashCode()和toString()方法。声明一个Record只需列出其组件。例如:
record Person(String name, int age) {} public static void main(String[] args) { Person person = new Person("Alice", 30); System.out.println(person); }
-
-
密封类 (Sealed Classes)
-
引入版本: 预览于JDK 15和JDK 16,正式引入是在JDK 17。
-
如何使用: 密封类限制了类的继承,允许你明确指定哪些类可以继承这个密封类。这有助于创建更可控、更易于理解的类层次结构。声明密封类时使用
sealed关键字,并用permits指定允许的子类。例如:sealed class Shape permits Circle, Rectangle { // ... } final class Circle extends Shape { // ... } non-sealed class Rectangle extends Shape { // ... }
-
JDK 17 (2021年发布, LTS版本)
-
密封类正式引入: 限制类的继承路径。
-
Panama Project初步成果: 提升与非Java语言互操作性的API,如改进的Foreign Function Interface (FFI)。
Project Panama 是Java的一个重要项目,旨在增强Java与其他编程语言,尤其是C和C++之间的互操作性,以及提升对本机库访问的能力。其初步成果集中体现在几个关键领域,其中最重要的是改进的 Foreign Function Interface (FFI)。
FFI 是一个编程框架,允许一个程序调用另一个编程语言编写的代码。在Java的上下文中,这意味着Java程序能够直接调用C库中的函数,而不需要通过Java Native Interface (JNI) 这样的传统桥梁。Panama项目的FFI目标是简化这一过程,让Java开发者能以更安全、高效且易于维护的方式与外部库互动。
-
ZGC和Shenandoah作为默认选项的准备: 虽未成为默认,但持续优化以备未来使用。
-
统一日志记录体系结构: 异步日志刷新,提升日志处理效率。
异步日志刷新的基本概念: 在传统的同步日志记录方式中,应用程序在写入日志时会直接执行磁盘I/O操作,这通常是一个耗时的操作,尤其是在高并发或日志量大的场景下,可能会导致程序性能下降,甚至阻塞主线程。异步日志刷新则通过将日志记录操作与实际的磁盘写入操作分离,来解决这个问题。
如何实现异步日志刷新:
- 日志缓冲区:当应用需要记录日志时,不是直接写入磁盘,而是先将日志信息写入内存中的缓冲区。这样可以快速完成写入操作,几乎不阻塞当前线程。
- 后台线程处理:单独的后台线程(或线程池)负责将缓冲区中的日志批量写入磁盘。这个过程相对独立于主业务逻辑,即便写入操作耗时也不会影响到应用的响应速度。
- 刷盘策略:后台线程按照一定的策略(如定时、缓冲区满、紧急日志立即刷盘等)将日志从缓冲区刷新到磁盘。合理的刷盘策略可以在保证日志及时性和完整性的同时,最大化效率。
- 错误处理:异步过程中需要有完善的错误处理机制,确保即使在写入失败的情况下也能重试或记录错误日志,不影响主流程。
异步日志刷新的优势:
- 性能提升:由于减少了主线程等待I/O操作的时间,提升了应用程序的整体响应速度和吞吐量。
- 资源利用:后台线程可以在空闲时间处理日志写入,避免了高并发时对CPU和I/O资源的争抢。
- 降低延迟:对于要求低延迟的应用,异步模式可以减少因日志写入而导致的延迟。
- 日志处理灵活性:后台线程可以对日志进行额外处理,如压缩、加密或过滤,而不影响主业务逻辑。