Java 17 新特性
如果您想比较不同版本的 Java API,有一个很棒的工具Java Version Almanac。
我们跳过中间的版本直接对比Java8和Java17和我们开发有关的差异。
Java 17 特性
- 1. Java 17 与 Java 8:变化
- 2. 扩展switch表达式
- 2. 实例匹配
- 3. 密封类(Sealed Classes)
- 4. 文本块
- 5. 新的 Optional.orElseThrow() 方法
- 6. 其他小而精的 API 更改
- 7. 垃圾收集器
- 8. 容器意识
- 9. CDS档案
- 10. Java Flight Recorder 和 Java Mission Control
- 11. 你应该从 Java 8 迁移到 Java 17 吗?
- 小结
1. Java 17 与 Java 8:变化
添加了一个新的var关键字,允许以更简洁的方式声明局部变量。
// java 8
Map<String, List<MyDtoType>> myMap = new HashMap<String, List<MyDtoType>>();
List<MyDomainObjectWithLongName> myList = aDelegate.fetchDomainObjects();// java 10
var myMap = new HashMap<String, List<MyDtoType>>();
var myList = aDelegate.fetchDomainObjects()
我们不能使用var 关键字接收 lambda 的值:
var fun = MyObject :: mySpecialFunction;
// 导致编译错误:(方法引用需要明确的目标类型)
但是,可以在 lambda 表达式中可以使用var
boolean isThereAneedle = stringsList.stream().anyMatch((@NonNull var s) -> s.equals(“needle”));
2. 扩展switch表达式
java17的switch case 可以更容易地以更易读的方式分组(注意没有break!)。
DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
boolean freeDay = switch (dayOfWeek) {case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;case SATURDAY, SUNDAY -> true;
};
还允许从代码块内部返回值的yield 关键字,它实际上是一个从 case 块内部工作的返回 值,并通过其switch设置该值。
DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
boolean freeDay = switch (dayOfWeek) {case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {System.out.println("Work work work");yield false;}case SATURDAY, SUNDAY -> {System.out.println("Yey, a free day!");yield true;}
};
2. 实例匹配
java8时, 我们通常会写这样的代码
if (obj instanceof MyObject) {MyObject myObject = (MyObject) obj;// TODO
}
Java 现在可以在if 中创建一个局部变量, 它将替我们进行强转。
if (obj instanceof MyObject myObject) {// TODO
}
此外,声明的变量可以在if 条件中使用
if (obj instanceof MyObject myObject && myObject.isValid()) {// TODO
}
3. 密封类(Sealed Classes)
在switch 中的“no default”警告有没有让你烦恼?您涵盖了域接受的所有选项,但警告仍然存在。使用密封类就可以摆脱对instanceof 类型检查的警告的烦恼。
public abstract sealed class Animal permits Dog, Cat {}public final class Dog extends Animal {}public final class Cat extends Animal {}// 你可以这样获取他们而不用强迫症的写上else的默认结果。
if (animal instanceof Dog d) {return d.woof();
} else if (animal instanceof Cat c) {return c.meow();
}
4. 文本块
String myWallOfText = """
______ _ _
| ___ \ | | (_)
| |_/ / __ ___| |_ _ _ _ ___
| __/ '__/ _ \ __| | | | / __|
| | | | | __/ |_| | |_| \__ \
\_| |_| \___|\__|_|\__,_|___/
"""
可以转义换行符并将字符串保持为单行
String text = """
又是写bug的一天, \
又是加班的一天。
"""
这相当于
String text = "又是写bug的一天,又是加班的一天"。
文本块可用于在您的代码中保留合理可读的 JSON 或 XML 模板。
5. 新的 Optional.orElseThrow() 方法
MyObject myObject = myList.stream().filter(MyObject::someBoolean).filter((b) -> false).findFirst().get();
在get不到对象时,该方法会抛出异常。Java 10 在 Optional 中引入了一个新方法orElseThrow(),感觉没什么用处,get不到还是要抛出异常。但是考虑到程序的可读性,写上瞬间有点严谨的感觉。
MyObject myObject = myList.stream()
.filter(MyObject::someBoolean)
.filter((b) -> false)
.findFirst()
.orElseThrow();
6. 其他小而精的 API 更改
// invert a Predicate, will be even shorter with static import
collection.stream().filter(Predicate.not(MyObject::isEmpty)).collect(Collectors.toList());// String got some new stuff too
“\nPretius\n rules\n all!”.repeat(10).lines()..filter(Predictions.not(String::isBlank)).map(String::strip).map(s -> s.indent(2)).collect(Collectors.toList());// no need to have an instance of array passed as an argument
String[] myArray= aList.toArray(String[]::new);// read and write to files quickly!
// remember to catch all the possible exceptions though
Path path = Files.writeString(myFile, "Pretius Rules All !");
String fileContent = Files.readString(path);// .toList() on a stream()
String[] arr={"a", "b", "c"};
var list = Arrays.stream(arr).toList();
7. 垃圾收集器
从 Java 9 开始,G1 是默认的垃圾收集器。与 Parallel GC 相比,它减少了暂停时间,尽管它的总体吞吐量可能较低。G1的更新包括将未使用的已提交内存返回给操作系统的能力(JEP 346)。
ZGC 垃圾收集器已在 Java 11 中引入,并已在 Java 15 ( JEP 377 ) 中达到产品状态。它旨在进一步减少停顿。从 Java 13 开始,它也可以将未使用的已提交内存返回给操作系统 ( JEP 351 )。
JDK 14 中引入了 Shenandoah GC,并在 Java 15 ( JEP 379 ) 中达到了产品状态。它旨在保持低暂停时间并独立于堆大小。
更多的GC了解请转https://jet-start.sh/blog/2020/06/09/jdk-gc-benchmarks-part1。
在 Java 8 中如果您没有手动更改 GC,您仍然使用Parallel GC。简单地切换到 Java 17 可能会使您的应用程序运行得更快,并具有更一致的方法运行时间。切换到 ZGC 或 Shenandoah 可能会得到更好的结果。
最后,No-Op Garbage Collector(JEP 318),尽管它是一个实验性功能。这个垃圾收集器实际上不做任何工作,因此允许您精确测量应用程序的内存使用情况。如果您想保持尽可能低的内存操作吞吐量,则很有用。
8. 容器意识
Java 曾有一段时间不知道它正在容器中运行。它没有考虑容器的内存限制,而是读取可用的系统内存。因此,当您有一台具有 16 GB RAM 的机器,将容器的最大内存设置为 1 GB,并在其上运行 Java 应用程序时,该应用程序通常会失败,因为它会尝试分配比可用内存更多的内存容器。从 Java 10 开始,默认情况下启用容器集成。但是,这对您来说可能不是一个明显的改进,因为在 Java 8 更新 131 中引入了相同的更改,尽管它需要启用实验选项并使用-XX:+UseCGroupMemoryLimitForHeap。
9. CDS档案
为了使 JVM 启动得更快,CDS Archives 自 Java 8 发布以来经历了一些变化。从 JDK 12 开始,默认情况下启用在构建过程中创建 CDS 档案 ( JEP 341 )。JDK 13 ( JEP 350 ) 中的一项增强功能允许在每次应用程序运行后更新档案。
这篇文章演示了如何使用此功能来缩短应用程序的启动时间。
10. Java Flight Recorder 和 Java Mission Control
Java Flight Recorder ( JEP 328 ) 允许以较低的(目标 1%)性能成本监视和分析正在运行的 Java 应用程序。Java Mission Control允许摄取和可视化 JFR 数据。参阅教程以大致了解如何使用它以及从中可以获得什么。
11. 你应该从 Java 8 迁移到 Java 17 吗?
简而言之,是的,你应该这样做。如果您有一个大型、高负载的企业应用程序并且仍然使用 Java 8,那么您肯定会看到更好的性能、更快的启动时间、迁移后更低的内存占用。开发该应用程序的程序员也应该更开心,因为语言本身有许多改进。
然而,这样做的成本很难估计,并且会因使用的应用程序服务器、库和应用程序本身的复杂性(或者更确切地说,它使用/重新实现的低级功能的数量)而有很大差异。
如果您的应用程序没有自定义类加载器,没有严重依赖 Unsafe、大量 sun.misc 或 sun.security 用法,那么您可能会没事。请参阅这篇文章,了解您可能需要进行的一些更改。
从版本 8 开始,Java 中删除了一些东西,包括 Nashorn JS 引擎、Pack200 API 和工具、Solaris/Sparc 端口、AOT 和 JIT 编译器、Java EE 和 Corba 模块。有些东西仍然存在,但不赞成删除,例如 Applet API 或安全管理器。由于有充分的理由将它们移除,因此无论如何您都应该重新考虑它们在您的应用程序中的使用。
小结
Java17主要有如下几个特性:
JEP 306: Restore Always-Strict Floating-Point Semantics
JEP 356: Enhanced Pseudo-Random Number Generators
JEP 382: New macOS Rendering Pipeline
JEP 391: macOS/AArch64 Port
JEP 398: Deprecate the Applet API for Removal
JEP 403: Strongly Encapsulate JDK Internals
JEP 406: Pattern Matching for switch (Preview)
JEP 407: Remove RMI Activation
JEP 409: Sealed Classes
JEP 410: Remove the Experimental AOT and JIT Compiler
JEP 411: Deprecate the Security Manager for Removal
JEP 412: Foreign Function & Memory API (Incubator)
JEP 414: Vector API (Second Incubator)
JEP 415: Context-Specific Deserialization Filters
Java 17 新特性相关推荐
- 2022年最细Java 17新特性,是真的猛,被征服了!
SpringBoot 正式支持Java 17,Kafka3.0弃用Java8 Spring Boot 2.5.5是Spring Boot 第一个支持Java 17的版本.现在你已经可以从Spring ...
- Java 17新特性,快到起飞?惊呆了!
都说Java 8 是YYDS,那你注意到 Java 17 也是长期支持版本吗?目前按计划 JDK 19 将于今年 9 月发布 SpringBoot 正式支持Java 17,Kafka3.0弃用Java ...
- Java 17新特性,快到起飞?
都说Java 8 是YYDS,那你注意到 Java 17 也是长期支持版本吗?目前按计划 JDK 19 将于今年 9 月发布 SpringBoot 正式支持Java 17,Kafka3.0弃用Java ...
- Java 17 新特性:密封类
Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360.JDK 16中的JEP 397),最终定稿于JDK 17中的JEP 409.Seal ...
- Java 17 新特性尝鲜
JDK 17更新了包括14个特性,具体如下表所示: Restore Always-StrictFloating-Point Semantics 恢复始终严格模式(Always-Strict)的浮点语义 ...
- Java 17 VS Java 8: 新旧对决,这些Java 17新特性你不容错过
- Java 8新特性——default方法(defender方法)介绍
转载自 Java 8新特性--default方法(defender方法)介绍 我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码.接口中定义的方法必须在接口的非抽象子类中实现 ...
- Java 9 新特性概述
转载自 Java 9 新特性概述 Java 9 正式发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化.其中最重要的改动是 ...
- Java 11新特性
转载来源:https://juejin.im/post/5bb08accf265da0a87266d2a Java 11新特性 概述 美国当地时间9月25日,Oracle 官方宣布 Java 11 ( ...
最新文章
- 人脸识别中的margin损失函数
- 存储过程编写经验和优化措施
- JavaScript 要点(十四)HTML DOM 元素(节点)
- 1033 旧键盘打字 (20 分)(c语言)
- 【Java】线程通信的例子:用两个线程打印 1-100;生产者消费者问题
- 云服务器系统盘升级会不会丢失数据,云服务器 系统盘快还是数据盘快
- 20135302魏静静——linux课程第六周实验及总结
- mysql 锁怎么使用_Mysql锁一般使用
- Android嵌套滑动冲突
- 遇到local variable ‘e‘ referenced before assignment这样的问题应该如何解决
- vue封装element-ui的table组件,灵活配置表头实现表格内编辑,按钮,链接等功能。...
- 数据密集型系统设计pdf下载
- 计算机毕业论文技术可行性怎么写,毕业论文怎么写可行性分析?
- winhex使用教程(详细版)
- 存储、计算、分布式知识点思维导图(收集整理适合小白)
- asp.net html silverlight 传参数,Silverlight和ASP.NET相互传参的两种常用方式(QueryString,Cookie)...
- 极客假日礼物指南(我们喜欢的极客资料)
- springboot+jsp人事工资管理系统 java ssm maven
- radis安装和使用
- 大数据下的小媒体——访新蓝网副总监洪永和