Java历代版本新特性
# 前言
从2017年9月,Java 9发布开始。Java版本的发布周期从之前的每两年一个新版本缩减到每六个月一个新版本。Java的变化开始迅猛起来。
为了更好的了解Java的发展历程,以及每个版本的新特性,本文从Java1.1版本开始,介绍了Java的发展历程,以及每个版本的新特性。
# 1.1
1997年2月19日发布 (opens new window)。
JavaBeans API允许开发人员编写可重用的组件,只需编写一次,然后可以在任何地方运行。
大幅改进的AWT,采用修订后的图形用户界面(GUI)基础,使开发人员能够创建高性能、复杂的GUI应用程序和小程序,在流行的个人电脑环境中表现出色。
强大的新功能,包括用于数据库连接的JDBC™,用于远程对象访问的RMI,以及其他Java安全API。
基于Unicode 2.0标准的全球语言支持。
# 1.2
1998年12月8日发布 (opens new window),代号为Playground。
- Java安全模型。先进的"沙箱"模型扩展,使开发人员、用户和系统管理员能够指定和管理一组灵活的安全策略,规定应用程序或小程序可以执行或不能执行的操作。Java 2平台安全模型包括以下新功能:
- 基于策略的访问控制
- 证书接口(X.509 V3)
- 性能增强。Java 2平台的改进性能和响应能力包括:
- Solaris操作环境的本机线程支持
- 加载类的内存压缩
- 更快的内存分配和改进的垃圾回收
- 可插拔的虚拟机体系结构,支持其他虚拟机,包括即将推出的Java HotSpot VM
- 新的即时编译器(JIT)
- Java本机接口(JNI)转换
- Java基础类(JFC)。Java基础类现已成为Java 2平台的核心,包括:
- 项目Swing GUI组件集
- 拖放功能
- Java 2D API,提供新的2D和AWT图形功能以及打印支持
- Java外观接口
- 新的辅助功能API
- 全球化。Java 2技术中增强的全球化为跨文化环境提供以下功能:
- 输入法框架(支持日语、中文和韩文字符)
- 使用Java 2D API实现复杂输出,提供日语、阿拉伯语、希伯来语和其他字符语言的双向高质量显示
- Java插件。Java插件现已包含在Java 2平台中,为Web浏览器提供了与Java虚拟机完全兼容的运行时环境,用户可以通过广泛部署的Web浏览器进行轻松下载和安装。
- Java接口定义语言(IDL)API。Java IDL API提供了基于标准的与CORBA的分布式计算互操作性。该API包括以下功能:
- 调用操作或远程网络服务
- 运行时环境中包含一个完全兼容的Java ORB
- Java数据库连接2.0(JDBC 2.0)增强。JDBC提供更灵活的查询数据访问。可滚动的游标和对SQL3类型的支持提供了更好的性能和稳定性。
- 集合框架。这种新的统一架构用于表示和操作集合,提高了开发效率,并允许不相关的API之间的互操作性。
- Java 2平台是符合2000年问题的;它是一个稳定、安全和强大的环境,适用于下一个千年的关键任务计算。
# 1.3
2000年5月发布 (opens new window)。随着 Java HotSpot Client VM 的加入,这是迄今为止最快的 Java 平台版本:与 J2SE 技术的初始版本相比,J2SE 技术 v1.3 的启动时间缩短了40%,与以典型方式使用 Java 基础类的应用程序相比,RAM 占用空间减少了25%。
- 极大提升的性能。Java HotSpot客户端虚拟机和经过优化的库使得J2SE v 1.3版本成为迄今为止最快的版本。J2SE技术v 1.3消除了性能作为企业考虑将Java 2平台作为其客户端策略的因素。
- 更轻松的Web部署。新功能,如小程序缓存和通过Java插件技术安装Java可选包,增强了基于Java技术的小程序和应用程序部署的速度和灵活性。Java插件技术是Java 2运行时环境标准版v 1.3的组件,使得基于Java技术的小程序和应用程序能够执行。
- 安全增强。对RSA电子签名、动态信任管理、X.509证书和Netscape签名文件验证的新支持意味着开发人员有更多的方式来保护电子数据。
- 开发的便利性。J2SE技术v 1.3版本中的众多新功能和开发工具使得基于Java技术的强大的Web应用程序或独立应用程序的开发更加简便和快捷。
- 企业互操作性。在J2SE 1.3版本中添加了RMI/IIOP和Java命名和目录接口(JNDI),增强了Java 2平台标准版的企业互操作性。RMI/IIOP改进了与支持CORBA的后端系统的连接性。JNDI提供了对支持流行的轻量级目录访问协议(LDAP)等协议的目录的访问。
- Java Platform Debugger Architecture (JPDA)
- 音频处理API(JavaSound)
- 用于实现动态代理的类(java.lang.reflect.InvocationHandler)
# 1.4
2002年2月发布 (opens new window),代号为Merlin。通过 Java Community Process(JCP) 开发的第一个 J2SE 发行版,JCP 是一个开放的、基于社区的过程,用于开发 Java 技术规范、参考实现和相关技术兼容性工具包。
Java 2平台标准版(J2SE)1.4是Java技术的最新版本,包括许多新功能和增强功能,以提高开发人员的生产力。J2SE 1.4包括Java 2平台企业版(J2EE)1.3,Java 2平台微型版(J2ME)1.3和Java Web Services开发包(JWSDP)1.0。
- 性能提升。基于使用 SPECjbb2000(Java Business Benchmark)的测试,标准性能评估公司用于衡量服务器端 Java 性能的基准测试,版本 1.4 显示比 J2SE 版本 1.3.1 提高了 58%。Java 客户端应用程序也得到了显著的改进,基于 Swing 的小程序和应用程序在 GUI 响应能力方面平均提高了 40%。
- assert 关键字 (在 JSR 41 中被指定)
- 仿照Perl的正则表达式
- 异常链,允许一个异常来封装原先处于较低级别的异常
- 支持Internet Protocol version 6 (IPv6)
- 非阻塞I/O(取名为 Nonblocking Input/Output,NIO)(在 JSR 51中被指定)
- 日志API (在JSR 47中被指定)
- 图像 I/O API来读取和写入图片,支持JPEG、PNG等格式
- 集成了XML解析器和XSLT处理器(JAXP)(指定在JSR 5和JSR 63)
- 集成安全和加密扩展组件(JCE, JSSE, JAAS)
- 内置了Java Web Start (Java Web Start 在2001年3月第一次被发布,作为J2SE 1.3的可选组件) (指定在JSR 56)
- 首选项 API (java.util.prefs),存储用户和系统的偏好设置
# 5.0
2004年9月发布 (opens new window),代号为Tiger。
从此版本开始,推出了一个新的版本控制系统。
版本号"1.5.0"和"5.0"均用于标识Java 2平台标准版的此版本。"5.0"是产品版本,而"1.5.0"是开发者版本。数字"5.0"用于更好地反映J2SE的成熟度、稳定性、可扩展性和安全性。
- 泛型(Generics): 为集合提供编译期间 (静态) 类型安全,且不须为大多数类型转换(规范在 JSR 14)
- 元数据(Metadata): 也称作注解。让语言结构(像是类别和方法)能够用额外的资料标记,可以由元数据工具处理(规范在 JSR 175)
- 自动封装与解封装: 在基本的资料类型(如 int)和基本的的外覆类别 (如 Integer) 之间能够自动转换 (规范在 JSR 201)
- 枚举(Enumerations): 以 enum 关键字创造出一种类型安全,有排序值的清单(如Day.MONDAY、 Day.TUESDAY 等);以前这只能透过非类型安全的恒定整数或自行撰写的类别来达成 (类型安全的枚举模式) (规范在JSR 201)
- 可变参数函数(Varargs):方法的最后一个参数现在可以用一个类型名称加上三个点宣告(如:void drawtext(String... lines));在调用代码中,类型中参数里任何的数字可以被使用,而它们再放在一个数组来传递给方法,或是其它的调用代码可以传递那个类型的数组
- 强化 for each 循环:for 循环的语法被用特别的语法扩展了,适用于数组或 Iterable,用于迭代每个成员,如基本的 Collection 类别 (规范在 JSR 201)
- 改进多线程 Java 程序的执行语义;新的 Java 存储器模型改善了复杂性、 有效性和以前的规格性能
- 静态导入
- 自动给RMI产生桩模块
- Swing:新的接口外观,叫做synth
- 异步实用工具。在 java.util.concurrent 包中。参考 Java 并发系列教程
- Scanner类解析来自各式各样的输入和缓冲
- 新的 ProcessBuilder 类提供了一种比 Runtime.exec 更方便的子进程调用方式。参考 Guide to java.lang.ProcessBuilder API (opens new window)
# 6
2006年12月发布 (opens new window),代号为Mustang。
从此版本开始,“J2SE”改为“Java SE”,“J2EE”改为“Java EE”,“J2ME”改为“Java ME”。
- 支持旧的Win9x版本;非正式地,Java 6 Update 7是Java的最后一个显示为在这些版本的Windows上工作的版本。
- 脚本语言支持(Scripting Language Support)(JSR 223):用于与脚本语言紧密集成的通用API,以及内置的Mozilla JavaScript Rhino集成。
- 核心平台和Swing性能显著的改进。
- 透过JAX-WS改善的网络服务支持(JSR 224).
- 支持JDBC 4.0 (JSR 221).
- Java编译器API (JSR 199):允许Java程序以写程序的方式选择和调用Java编译器的API。
- 将JAXB升级到版本2.0:包括StAX解析器的集成。
- 支持pluggable annotations (JSR 269)。 参考 Java运行期动态能力
- 改善许多GUI,像是SwingWorker在API中的集成,表格排序和筛选,以及真正的Swing双缓冲(消除模糊区域效果)。
- 包含JVM改善:同步和编译器性能优化,新算法和对现有垃圾收集算法的升级以及应用程序启动性能。
# 7
2011年7月发布 (opens new window),代号为Dolphin。
- JVM本身对动态语言的支持:新的invokedynamic字节码指令 (opens new window)(JSR-292),与多语言虚拟机(Multi Language Virtual Machine)原型
- 64位指针压缩(Java 6 中可以使用 XX:+UseCompressedOops 开启)
- 一些语言方面的小改变(在Coin项目下的一个小群体):
- 在switch中使用字符串类型。例如:
switch (str) {case "abc": ...}
- try语句中的自动资源管理。例如:
try (FileWriter writer = new FileWriter("file.txt")) {}
- 针对泛型实例的创建而改善的类型推论,被称为钻石操作符<>。例如:
Map<String, List<String>> myMap = new HashMap<>();
- 简化了varargs方法的声明,可以直接使用参数类型后加上省略号
...
来声明可变参数 - 二进制整数字面值,以前缀0b或0B开头。例如:
int binary = 0b1001;
- 允许在数值字面值中加入下划线。下划线可以插入在数字之间,但不能放在开头或结尾。例如:
1_000_000
- 允许在一个 catch 中捕捉多个类型的异常,并使用改进的类型检查重新抛出异常。例如:
catch (IOException|SQLException ex) {throw ex;}
- 在switch中使用字符串类型。例如:
- JSR 166下的并发实用工具(ForkJoinPool (opens new window)、Phaser、ConcurrentLinkedDeque和TransferQueue)
- 新的文件 I/O 程序库 (JSR 203 定义) 增加多重文件的支持、文件原始资料和符号链接。新的包为:java.nio.file (opens new window)、java.nio.file.attribute和java.nio.file.spi
- 使用 Timsort 来为集合与数组排序,取代归并排序
- 对椭圆曲线加密算法增加标准库级别的支持
- 一个给Java 2D的XRender传递途径,改进了现代GPUs特有的功能的处理
- 用于图形功能的新平台API(最初在版本6u10中的实现为不支持的API)
- 增强了对新网络通信协议(包括SCTP和Sockets Direct Protocol)的标准库级别的支持
- 更新对XML和Unicode的支持,以符合最新标准
- Java部署规则集
# 8(LTS)
2014年3月18日发布 (opens new window)。
Java 8 不再支持 Windows XP,但JDK 8 第 25 版更新仍然可以在 Windows XP安装和运行。
- JSR 335,JEP 126:Lambda项目中提供的语言级匿名函数支持(官方称为 lambda 表达式,非官方亦称闭包);添加默认方法(虚拟扩展组件方法) ,以允许在不破坏兼容性的情况下向现有接口中新增方法。Java社群中曾经有过针对是否要加入 lambda 表达式支持的辩论。稍后Sun公司宣布 lambda 表达式将会包含在Java中,并请社群协助改善该特性。支持lambda表达式使得针对流中元素的函数式操作成为可能,由此可以实现由 MapReduce 启发的函数式集合操作。默认方法允许API作者添加新的方法到现有接口上,而不会破坏旧的代码中。默认方法还使得多重继承的行为 (不是状态)成为可能,但默认方法的设计意图并非在此。参考:Java8--Lambda 表达式、Stream 和时间 API
- JSR 223,JEP 174:Nashorn项目,一个 JavaScript 运行时,它允许开发人员在应用程序中嵌入 JavaScript 代码
- JSR 308,JEP 104:在 Java 类型上的注解(@NonNull、@Nullable、@Mutable等)
- 无符号整数算术
- JSR 337,JEP 120:重复注解
- JSR 310,JEP 150:日期和时间 API,基于Joda-Time日期时间处理库的实现。
- JEP 178:静态链接 JNI 程序库
- JEP 153:执行 JavaFX 应用程序(直接执行 JavaFX 的应用程序的 JAR 包)
- JEP 122:移除了虚拟机内存管理中的永久世代
# 9
2017年9月发布 (opens new window)。
- JSR 376:在Jigsaw项目中将JDK模块化 (opens new window)
- JEP 222:jshell:Java Shell (opens new window)(一个 Java 交互式顶层构件)
- JEP 295:AOT编译(通过 GraalVM 实现)
- JEP 268:XML Catalogs(对XML目录的支持)
- JEP 266:更多的并发更新。包含响应式流的Java实现,及其部分替代品java.util.concurrent.Flow (opens new window)。
- JEP 193:变量句柄:定义一个标准方法来调用java.util.concurrent.atomic和sun.misc.Unsafe操作的等价物。VariableHandles (opens new window)类提供了一组静态方法,可以用来创建变量句柄,并使用统一的语法来完成原子操作、内存访问等操作。这些方法可以替代原子变量和Unsafe类中的方法,为开发人员提供更直观和易于使用的API。
- JEP 282:jlink (opens new window):Java链接器。该工具可以为模块生成一个包含了其所有依赖项的自定义运行时映像,同时允许生成一个包括运行它的JVM的可执行文件。
- JavaDB被移出JDK,其开发和维护是由Apache Derby社区负责。
- JEP 263:高DPI图像:自动缩放与尺寸自适应。改进Java应用程序在高分辨率显示屏幕上的图像质量和表现。
- JEP 158:Unified JVM Logging,统一的JVM日志记录 (opens new window)。提供了一种通用的日志记录系统,用于JVM组件和应用程序。
- API变动
- 集合工厂方法,比如List.of、Set.of、Map.of、Map.ofEntries
- Stream API新增takeWhile、dropWhile、iterate、ofNullable、iterate方法
- Optional新增stream方法
- 支持接口私有方法 (opens new window)
- Javadoc 支持 HTML5
- 不能使用下划线 _ 作为变量名,因为它是一个关键字
- String 存储结构变更从 char -> byte
- 新增ProcessHandle类 (opens new window),用于简化处理进程
# 10
2018年3月发布 (opens new window)。
- JEP 286:局部变量类型推断(var关键字)。例如:
for (var integer : list){ }
- JEP 317:实验性的基于Java的JIT编译器。这是 Linux x64 下 Graal 动态编译器的集成。
- JEP 310:应用程序类级别数据共享(CDS)
- JEP 307:适用于G1的多线程完全垃圾回收。通过
-XX:+UseParallelGC
参数启用。 - JEP 304:垃圾回收器接口
- JEP 314:更多的Unicode语言标签扩展
- JEP 319:内置根证书
- JEP 312:线程本地握手
- JEP 316:在可选的内存设备上申请堆内存空间
- JEP 313:删除本地代码头文件生成器javah
- JEP 296:将所有JDK分支集成到同一个版本库中
- 容器意识,JVM现在知道自己在Docker容器中运行,并将提取特定于容器的配置,而不是查询操作系统本身。新增参数-XX:-UseContainerSupport、-XX:ActiveProcessorCount、-XX:InitialRAMPercentage、-XX:MaxRAMPercentage、-XX:MinRAMPercentage
- API变动
- 新增了
Optional.orElseThrow()
方法 - 新增了
Collection.copyOf()
方法,拷贝之后集合不可变 - 新增了
Collectors.toUnmodifiableList()
方法 - 新增了
Collectors.toUnmodifiableSet()
方法 - 新增了
Collectors.toUnmodifiableMap()
方法
- 新增了
# 11(LTS)
2018年9月发布 (opens new window)。
- JEP 181:针对嵌套成员的访问控制 (opens new window)
- JEP 309:动态类文件常量
- JEP 315:利用 Aarch64 的特有架构改进其上的性能
- JEP 318:Epsilon:无操作垃圾收集器
- JEP 320:移除 Java EE 和 CORBA 模块
- JEP 321:HTTP Client
- JEP 323:lambda参数的局部变量语法。例如:
hashMap.forEach((var k, var v) -> { });
- JEP 324:支持 Curve25519 和 Curve 448 密钥
- JEP 327:Unicode 10
- JEP 328:添加Java飞行记录器(JFR),其用于创建性能分析记录
- JEP 329:ChaCha20 和 Poly1305 加密算法
- JEP 330:运行单文件源码程序 (opens new window)
- JEP 331:低开销堆分析
- JEP 332:支持 TLS 1.3
- JEP 333:添加ZGC(一个可扩展的低延迟垃圾收集器)
- JEP 335:弃用 Nashorn JavaScript 引擎
- JEP 336:弃用 Pack200 相关的工具及 API
- API变动
- String中新增了
repeat()
、isBlank()
、lines()
、strip ()
--去除空白 方法 - Files中新增了
readString()
、writeString()
方法 - Collections新增了toArray方法,例如
sampleList.toArray(String[]::new)
- Predicate新增了
not()
方法,用于谓语否定
- String中新增了
# 12
2019年3月发布 (opens new window)。
- JEP 189:Shenandoah:一个实验性的低延迟垃圾收集器
- JEP 230:细粒度性能评审包
- JEP 325:Switch 表达式(预览阶段)
public static void switchJava12(String day) { switch (day) { case "march", "april", "may" -> System.out.println("春天"); case "june", "july", "august" -> System.out.println("夏天"); case "september", "october", "november" -> System.out.println("秋天"); case "december", "january", "february" -> System.out.println("冬天"); } } String season = switch (day) { case "march", "april", "may" -> "春天"; case "june", "july", "august" -> "夏天"; case "september", "october", "november" -> "秋天"; case "december", "january", "february" -> "冬天"; default -> { //throw new RuntimeException("day error") System.out.println("day error"); break "day error"; } }; System.out.println("当前季节是:" + season);
- JEP 334:JVM Constants API(ClassDesc, MethodTypeDesc, MethodHandleDesc, DynamicConstantDesc)
- JEP 340:仅保留一个 AArch64 平台的移植
- JEP 341:默认类数据共享归档
- JEP 344:针对G1,提供可中止的混合垃圾收集
- JEP 346:针对G1,及时释放已申请但未使用的内存
- 支持Unicode 11,支持操作更多的表情、符号
- API改动
- 新增了
String.indent()
--调整每行开头缩进、String.transform()
--转换方法 - 新增了
Files.mismatch()
方法,用于文件对比。比较两个文件并查找其内容中第一个不匹配字节的位置,如果文件相同,则为-1L - 新增了
Collectors.teeing()
方法,它是两个下游收集器的组合,每个元素都由两个下游收集器处理。然后,它们的结果被传递给合并函数并转换为最终结果 - 紧凑数字格式的CompactNumberFormat,用于格式化数字,例如:
NumberFormat.getCompactNumberInstance(Locale.CHINA, CompactStyle.SHORT)
@Test public void givenNumber_thenCompactValues() { NumberFormat likesShort = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT); likesShort.setMaximumFractionDigits(2); assertEquals("2.59K", likesShort.format(2592)); NumberFormat likesLong = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG); likesLong.setMaximumFractionDigits(2); assertEquals("2.59 thousand", likesLong.format(2592)); }
- 新增了
# 13
2019年9月发布 (opens new window)。
- JEP-350: 动态 CDS 归档。可以在应用程序退出时生成共享存档,这消除了试运行的需要。使用-XX:SharedArchiveFile参数
- JEP-351: ZGC: 取消提交未使用存储器
- JEP-353: 重新实现旧版 Socket API
- JEP-354: Switch 表达式(预览阶段)。从12的直接返回,变成了使用yield返回
public static String switchJava13(String month) { return switch (month) { case "march", "april", "may": yield "春天"; case "june", "july", "august": yield "夏天"; case "september", "october", "november": yield "秋天"; case "december", "january", "february": yield "冬天"; default: yield "month error"; }; }
- JEP-355: 文本块(预览阶段)。String中也新增了三个方法:stripIndent--删除空白、translateEscapes--将转义序列(如“\t”转换为“\t”)、formatted--与String::format的工作方式相同,但用于文本块
String TEXT_BLOCK_JSON = """ { "name" : "Baeldung", "website" : "https://www.%s.com/" } """;
- 支持Unicode 12.1
# 14
2020年3月发布 (opens new window)。
- JEP-305:使用 instanceof 的模式匹配(预览)
public static void main(String[] args) { Object obj = "hello"; if (obj instanceof String str) { System.out.println(str.toUpperCase()); } else { System.out.println(obj); } }
- JEP-343:打包工具(孵化中)
- JEP-345:在 G1 中,对不均匀的内存访问(NUMA)情况下的内存申请优化
- JEP-349:JFR Event Streaming
- JEP-352:使字节缓冲区能够映射到非易失性存储器上
- JEP-358:有帮助的 NullPointerExceptions,定位到变量
- JEP-359:记录类(预览),关键字为record。例如:
public record Person(String name, int age) {}
,效果和lombok的@Data类似 - JEP-361:Switch 表达式(标准)。和12中的预览一直,去除了13中的yield关键字用法
- JEP-362:弃用 Solaris 和 SPARC 平台上的移植版本
- JEP-363:移除 Concurrent Mark Sweep (CMS) 垃圾收集器
- JEP-364:适用于 macOS 的 ZGC
- JEP-365:适用于 Windows 的 ZGC
- JEP-366:弃用 ParallelScavenge + SerialOld 的垃圾收集器组合
- JEP-367:移除 Pack200 相关的工具及 API
- JEP-368:文本块(第二预览版本)。新增了两个转义符:1、
\
结尾不换行;2、\s
表示一个空格 - JEP-370:外部内存访问 API (opens new window)(孵化中),基于MemorySegment、MemoryAddress 和 MemoryLayout三个类
# 15
2020年9月发布 (opens new window)。
- JEP 339:爱德华曲线数字签名算法 (EdDSA)
- JEP 360:密封类(预览)有些时候我们可能想让某个类可以被某些类型继承,但是又不能随意继承,是做不到的。Java 15 尝试解决这个问题,引入了 sealed 类,被 sealed 修饰的类可以指定子类。这样这个类就只能被指定的类继承。(sealed 、non-sealed、permits关键字)
- JEP 371:隐藏类 (opens new window)。隐藏类不需要经过类加载器的完整加载和扫描过程,可以提供更好的性能,lambda表达式使用隐藏类来实现。
- JEP 372:移除 Nashorn JavaScript 引擎
- JEP 373:重新实现 DatagramSocket API
- JEP 374:禁用并弃用偏向锁
- JEP 375:使用 instanceof 的模式匹配(第二预览版本)
- JEP 377:ZGC: 可伸缩的低延迟垃圾收集器。参考:亚毫秒GC暂停到底有多香?JDK17+ZGC初体验 (opens new window)
- JEP 378:文本块 (opens new window)
- JEP 379:Shenandoah: 低暂停时间的垃圾收集器
- JEP 381:移除 Solaris 和 SPARC 平台上的移植版本
- JEP 383:外部内存访问 API(第二孵化版本)
- JEP 384:记录类(第二预览)
- JEP 385:弃用 RMI Activation 以待后续移除
# 16
2021年3月发布 (opens new window)。
- JEP 338:Vector API(孵化)
- JEP 347:启用 C++14 语言特性
- JEP 357:从 Mercurial 迁移到 Git
- JEP 369:迁移到 GitHub
- JEP 376:ZGC: 并发的线程栈处理
- JEP 380:用于 Unix 域套接字的 Channel
- JEP 386:Alpine Linux 的移植版本
- JEP 387:可伸缩的 Metaspace
- JEP 388:Windows/AArch64 的移植版本
- JEP 389:外部链接器 API(孵化)
- JEP 390:对值类型的类(Value-based Classes)发出警告
- JEP 392:打包工具
- JEP 393:外部内存访问 API(第三孵化版本)
- JEP 394:使用 instanceof 的模式匹配
- JEP 395:记录类 (opens new window)
- JEP 396:在缺省情况下对 JDK 内部进行强封装,也就是默认
–-illegal-access=deny
- JEP 397:密封类(第二预览版本)
- API变动
- 新增Stream.toList()、Stream.toSet()方法
- 代理类中支持调用default方法
interface HelloWorld { default void hello() { return "hello"; } } Object proxy = Proxy.newProxyInstance(getSystemClassLoader(), new Class<?>[] { HelloWorld.class }, (prox, method, args) -> { if (method.isDefault()) { return InvocationHandler.invokeDefault(prox, method, args); } // ... } ); Method method = proxy.getClass().getMethod("hello"); assertThat(method.invoke(proxy)).isEqualTo("world");
- DateTimeFormatter新增了时段符号“B”,可用于替换am/pm
LocalTime date = LocalTime.parse("15:25:08.690791"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h B"); assertThat(date.format(formatter)).isEqualTo("3 in the afternoon");
# 17(LTS)
2021年9月发布 (opens new window)。
- JEP 306:将浮点数的默认语义恢复为严格的.在Java之前的版本中,浮点数的默认语义是基于IEEE 754浮点数规范的,其中包含了一些近似规则,如舍入误差和浮点数操作的一些特殊情况。而在Java 17中,由于许多开发人员希望在浮点数计算中获得更加精确和一致的结果,Java的默认浮点数语义被更改为严格的模式。这意味着在进行浮点数计算时,将使用更严格的规则来处理舍入误差和浮点数操作的边缘情况,以确保更准确的结果。
- JEP 356:加强的伪随机数生成器
- JEP 382:新的 macOS 渲染管线
- JEP 391:macOS/AArch64 的移植版本
- JEP 398:弃用 Applet API,以待后续移除
- JEP 403:对 JDK 内部进行强封装
- JEP 406:使用 switch 的模式匹配(预览),支持null值的匹配
- JEP 407:移除 RMI Activation
- JEP 409:密封类 (opens new window)
- JEP 410:移除实验性的 AOT 与 JIT 编译器
- JEP 411:弃用安全管理器,以待后续移除
- JEP 412:外部函数与内存 API(预览)
- JEP 414:Vector API(第二预览版本)
- JEP 415:限定上下文的反序列化过滤器
# 18
2022年3月发布 (opens new window)。
- JEP 400:默认使用 UTF-8
- JEP 408:简易 Web 服务器。使用 jwebserver 启动一个 Web 服务器,默认发布的是当前目录。
- JEP 413:Java API 文档中的代码片段,使用@snippet标记
- JEP 416:使用 Method Handle 重新实现核心反射
- JEP 417:Vector API(第三孵化版本)
- JEP 418:因特网地址解析 SPI
InetAddress inetAddress = InetAddress.getByName("www.wdbyte.com"); System.out.println(inetAddress.getHostAddress()); // 输出 // 106.14.229.49
- JEP 419:外部函数与内存 API(第二预览版本)
- JEP 420:使用 switch 的模式匹配(第二预览版本)。判断的时候支持复杂表达式:
case Triangle t && (t.calculateArea() > 100)
;case的时候可以进行类型判断:case A a -> 1;
- JEP 421:弃用Finalization,以待后续移除
# 19
2022年9月发布 (opens new window)。
- JEP 405:Record 模式匹配(预览)。例如:
if(dog1 instanceof Dog(String name,Integer age)){}
- JEP 422:Linux/RISC-V 的移植版本
- JEP 424:外部函数与内存 API(预览)
- JEP 425:虚拟线程(预览),
Executors.newVirtualThreadPerTaskExecutor()
创建虚拟线程池 - JEP 426:Vector API (opens new window)(第四预览版本)
- JEP 427:使用 switch 的模式匹配(第三预览版本)
- JEP 428:结构化并发 (opens new window)(孵化)
# 20
2023年3月发布 (opens new window)。
- JEP 429:作用域值 (opens new window)(孵化)
- JEP 432:记录类的模式匹配(第二预览版本)
- JEP 433:使用 switch 的模式匹配(第四预览版本)。对判断部分进行了增强,
case String s when s.length() > 2 -> "是个字符串,长度大于2";
- JEP 434:外部函数与内存 API(第二预览版本)
- JEP 436:虚拟线程(第二预览版本)
- JEP 437:结构化并发(第二孵化版本)
# 21(LTS)
2023年9月发布 (opens new window)。
- JEP 430: 字符串模板(预览) (opens new window)
- JEP 431: 顺序集合 (opens new window)
- JEP 439: 分代ZGC
- JEP 440: 记录类的模式匹配
- JEP 441: switch的模式匹配
static String formatterPatternSwitch(Object obj) { return switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> obj.toString(); }; }
- JEP 442: 外部函数与内存API(第三版预览)
- JEP 443: 未命名的模式和变量(预览)
- JEP 444: 虚拟线程 (opens new window)
- JEP 445: 无名类和实例主方法(预览) (opens new window)
- JEP 446: 作用域值(预览)
- JEP 448: 矢量API(第六个孵化器)
- JEP 449: 弃用Windows 32位x86端口以供移除
- JEP 451: 准备禁止动态加载代理
- JEP 452: 密钥封装机制API
- JEP 453: 结构化并发(预览)
# 22
2024年3月发布 (opens new window)。
- JEP 423: G1的区域固定。通过在 G1 中实现区域固定来减少延迟,以便在 Java 本机接口 (JNI) 关键区域期间无需禁用垃圾收集。
- JEP 447: 在super(...)之前的语句(预览)。允许构造函数中在super()之前进行条件验证等语句的存在
- JEP 454: 外部函数与内存API (opens new window)
- JEP 456: 未命名的模式和变量 (opens new window)
- JEP 457: Class-File API(预览) (opens new window)
- JEP 458: 启动多文件源代码程序
- JEP 459: 字符串模板(第二次预览)
- JEP 460: 矢量API(第七个孵化器)
- JEP 461: 流收集器(预览) (opens new window)
- JEP 462: 结构化并发(第二次预览)
- JEP 463: 隐式声明的类和实例主方法(第二次预览)
- JEP 464: 作用域值(第二次预览)
# 23
2024年9月发布 (opens new window)。
- JEP 455: 支持instanceof和switch中的原始类型(预览)。比如
if(i instanceof byte b)
,或者switch(i){ case int i -> ... ;}
- JEP 466: Class-File API(第二次预览)
- JEP 467: 支持Markdown文档注释
- JEP 469: 矢量API(第八个孵化器)
- JEP 473: 流收集器(第二次预览)
- JEP 471: 弃用sun.misc.Unsafe中的内存访问方法以供移除
- JEP 474: ZGC:默认的开启分代模式
- JEP 476: 模块导入声明(预览)。可以直接导入模块:
import module java.base
,这样会导入模块下的所有类 - JEP 477: 隐式声明的类和实例主方法(第三次预览)
- JEP 480: 结构化并发(第三次预览)
- JEP 481: 作用域值(第三次预览)
- JEP 482: 灵活的构造函数体(第二次预览)