Java 14Java 15新特性概述
一、Java 14
发布于2020年3月17日。Java 14主要新特性如下:
-
JEP 305:Pattern Matching for instanceof (Preview)instanceof 的模式匹配(预览)
-
JEP 358:Helpful NullPointerExceptions 有用的 NullPointerExceptions
-
JEP 359:Records (Preview) Records(预览)
-
JEP 361:Switch Expressions (Standard)Switch 表达式(转正)
-
JEP 363:Remove the Concurrent Mark Sweep (CMS) Garbage Collector删除并发标记清除 (CMS) 垃圾回收器
-
JEP 366:Deprecate the ParallelScavenge + SerialOld GC Combination弃用 ParallelScavenge + SerialOld GC 组合
-
JEP 368:Text Blocks (Second Preview)文本块(第二次预览)
-
JEP 370:Foreign-Memory Access API (Incubator) 外部内存访问 API (第一轮孵化)
更多内容请读者自行阅读:OpenJDK Java 14官方文档
1.1 JEP 305:instanceof 的模式匹配(一次预览)
Java 14也对instanceof的使用进行了改进,看下面例子:
public static void main(String[] args) {Object obj = new Object();if(obj instanceof String){//强转为StringString str = (String) obj;String trim = str.trim();}//Java 14if(obj instanceof String str){//不必强转,直接使用String trim = str.trim();}
}
1.2 JEP 358:改进NEP异常提示信息
public class NEPTest {public static void main(String[] args) {User user=new User();System.out.println(user.getAddress().getCity().trim());}
@Datastatic class User{private String name;private Address address;}@Datastatic class Address{private String city;}
}
程序执行会报NPE异常,异常信息在Java 14进行了改进,我们先开java 14版本之前的报错信息:
Exception in thread "main" java.lang.NullPointerExceptionat com.lky.features.java14.NEPTest.main(NEPTest.java:11)
通过异常信息很容易就能定位到报错行,但是分辨不出是"user.getAddress()"是null还是"getAddress().getCity()"是null,我们再来看下Java 14的报错信息:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.lky.features.java14.NEPTest$Address.getCity()" because the return value of "com.lky.features.java14.NEPTest$User.getAddress()" is nullat com.lky.features.java14.NEPTest.main(NEPTest.java:11)
从报错信息一眼就可以看出是""User.getAddress()" 为null导致的。
1.3 JEP 359:Records(一次预览)
Java 14以预览功能的形式引入了一个新特性:Records,主要目的是提供一种简洁的语法来声明类似数据的小型不可变对象,用于解决长期以来Java中定义纯数据载体类带来的繁琐问题。
ps:Java 16才成为正式特性。
Java语言架构师Brian Goetz曾经写过一篇文章(http://cr.openjdk.java.net/~briangoetz/amber/datum.html )提到:开发人员想要创建纯数据载体类通常必须编写大量低价值、重复的、容易出错的代码,比如构造函数、getter/setter、equal()、hashCode()等方法。以至于很多人选择使用IDE的功能自动生成这些方法,还有一些会选择使用一些第三方类库,比如Lombok:
那么纯数据载体指的是什么呢,举个例子:
public class Student {private String name;private int age;
public Student(String name, int age) {this.name = name;this.age = age;}
public Student() {}//省略getter/setter()、toString()、hashCode()等方法
}
我们再看看Records的写法:
public record Student1(String name, int age) {
}
//使用
public static void main(String[] args) {Student1 student=new Student1("张三",12);int age = student.age();String name = student.name();
}
反编译一下:
public final class Student1 extends Record {private final String name;private final int age;public Student1(String string, int n) {this.name = string;this.age = n;}@Overridepublic final String toString() {return ObjectMethods.bootstrap("toString", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this);}@Overridepublic final int hashCode() {return (int)ObjectMethods.bootstrap("hashCode", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this);}@Overridepublic final boolean equals(Object object) {return (boolean)ObjectMethods.bootstrap("equals", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this, object);}public String name() {return this.name;}public int age() { return this.age;}
}
通过反编译得到的类(妥妥的是一个语法糖啊),我们可以看到:
生成了一个final修饰的Student1类,说明这个类不能有子类了。
类中有两个private final修饰的属性,所以record中的属性都是private final修饰的。
一个构造函数、两个getter方法还有hashCode()、toString()、equals()都是自动生成的。
还能干啥?前面的例子中我们创建了一个record,感觉空荡荡的,还能有其它成员变量和方法吗?当然能:
public record Student1(String name, int age) {//只能添加静态字段static int x;//静态方法public static void doSomething() {x++;}//实例方法public String getInfo(){return "姓名:"+name+",年龄:"+age;}//构造函数public Student1{if(age>=35){throw new IllegalArgumentException("年龄过大!!!");}}
}
就介绍这么多吧,总结一下它的优缺点:
优点:record非常适合作为再各层间传递数据载体,比如DTO;且它是不可变的,这也说明可以确保线程安全。
缺点:由于是不可变的,所以没有setter方法,通用性比较弱;且如果参数过多,写起来和看起来都不如传统的写法。
1.4 JEP 361: Swicth表达式(正式特性)
switch 表达式由 JEP 325 于 2017 年 12 月提出。JEP 325 于 2018 年 8 月作为预览功能针对 JDK 12。
JEP 354 提出了一个新的声明 yield,并恢复了 break 的原意。JEP 354 于 2019 年 6 月作为预览功能针对 JDK 13。
对 JDK 13 的反馈表明,switch 表达式已准备好在 JDK 14 中成为最终的永久表达式,无需进一步的更改。
最终版本可以参考以下代码示例:
public static String swicthDay(String x){String type;//Java 12:如果加一个if判断分支,那就不能用->直接返回了switch (x){case "Monday","Tuesday","Wednesday","Thursday","Friday"->type="WorkDay";case "Saturday","Sunday"->type="FreeDay";default -> {if(x.isEmpty()){type="null";}else {type="noDay";}}};
//java 13:可以用yield直接返回type = switch (x){case "Monday","Tuesday","Wednesday","Thursday","Friday"->"WorkDay";case "Saturday","Sunday"->"FreeDay";default -> {if(x.isEmpty()){yield "null";}else {yield "noDay";}}};return type;}
1.5 JEP 363:删除并发标记清除 (CMS) 垃圾回收器
也是由于高性能和高效率的垃圾回收器(G1、ZGC和Shenandoah等)层出不穷,CMS的技术也相对过时,Java 14正式删除了CMS垃圾回收器及其相关代码。
1.6 JEP 366:弃用ParallelScavenge+SerialOld GC组合
随着JVM发展,高性能和高效率的垃圾回收器(G1、ZGC和Shenandoah等)层出不穷,而对于ParallelScavenge+SerialOld这个组合已经不具备优势了,用的也越来越少,所以Java 14弃用了这个组合。
1.7 JEP 368:文本块(二次预览)
Java 13引入了文本块("""),Java 14对其进一步增强,新增了两个转义符:""和"\s":
" \ ":表示行尾,不引入换行符。
"\s":表示单个空格。
public static void main(String[] args) {String str1= """Hello,\World""";System.out.println(str1);//Hello,WorldString str2= """Hello\sWorld""";System.out.println(str2);//Hello World
}
1.8 JEP 370:外部内存访问API(第一轮孵化)
Java 14将外部内存访问 API作为孵化项目引入 ,以允许 Java 程序安全高效地访问 Java 堆外内存。
为什么要引入?
现在许多Java库或程序都会访问外部内存,比如Ignite、mapDB、RocketMQ、memcached和Netty的ByteBuf API等,通过访问外部内存,他们可以避免与GC打交道、在多个进程之间共享内存以及可以通过将文件映射到内存(通过mmap等)来序列化内存内容。
但是,现在Java提供的外部内存API并不好用。
Java 14之前,开发人员如果想要操作堆外内存,通常的做法就是使用ByteBuffer、Unsafe或JNI等方式,但无论哪种方式都无法有效解决安全性和高效性等2个问题,并且堆外内存的释放也是一个头疼的问题。
ps:这个在Java 17会与另一个孵化项目合并,并在Java 19进行第一次预览,所以更多内容请参考Java 19。
二、Java 15
Java 15于2020年9月15日发布,主要特性如下:
-
JEP 360:Sealed Classes (Preview) 封闭类(预览)
-
JEP 371:Hidden Classes 隐藏类
-
JEP 374:Disable and Deprecate Biased Locking 禁用和弃用偏向锁
-
JEP 375:Pattern Matching for instanceof (Second Preview)instanceof 的模式匹配(二次预览)
-
JEP 377:ZGC: A Scalable Low-Latency Garbage Collector ZGC:可扩展的低延迟垃圾回收器(转正)
-
JEP 378:Text Blocks 文本块(转正)
-
JEP 379:Shenandoah: A Low-Pause-Time Garbage Collector Shenandoah:低暂停时间垃圾收集器(转正)
-
JEP 383:Foreign-Memory Access API (Second Incubator) 外部内存访问 API(第二个孵化器)
-
JEP 384:Records (Second Preview) Records(第二次预览)
更多内容请读者自行阅读:OpenJDK Java 15官方文档
2.1 JEP 360:封闭类(一次预览)
Java 15之前,Java认为"代码重用"始终是一个终极目标,所以一个类或接口都可以被任意的类继承或实现。
但是在很多场景中,这样做反而容易造成错误,比如某些公司只要具有985或211学历的人;那么在Java中创建Company抽象类时,应该只允许Work985和Work211类去扩展它。
通过这种方式,我们希望确保在域内不会出现误用Worker抽象类的情况,为了解决类似问题,Java 15引入了封闭类:
封闭类用sealed修饰,它的所有子类都必须在同一个模块或包内。
封闭类使用permits来指定允许继承的子类。
封闭类的子类可以被声明为non-sealed或final。non-sealed可以被继承,final则不能。
//密封类
//接口写法
public sealed interface Company permits Worker985,Worker211 {
}
//抽象类写法
public abstract sealed class Company1 permits Worker985,Worker211 {
}
//子类
public final class Worker985 implements Company {
}
//非密封子类
public non-sealed class Worker211 implements Company {
}
2.2 JEP 371:隐藏类
这是一种不能被其他类直接使用的类,Java 15引入隐藏类主要针对的时库和框架的开发者,所以大多数程序员就都用不到了;
简单的说,隐藏类不是通过常规的Java代码创建的,而是通过特定的API调用在运行时动态生成的。
2.3 JEP 374:禁用偏向锁定
在之前文章Java并发编程第4讲——Java中的锁(万字详解)介绍synchronized锁升级过程的时候提到了过:
偏向锁:指在只有一个线程访问对象的情况下,也就是没有竞争,可以直接执行代码,并在对象头中记录该线程的ID作为偏向锁的持有者。
标记目的是JVM会假定这个线程会再次获得该锁,因此在下次获取锁的时候就可以省略一些与锁相关的检查和更新操作,从而提高性能。
但是,偏向锁增加了JVM的复杂性,并且在多线程竞争激烈的情况下,他可能不会带来预期的性能提升,所以在Java 15中,默认禁用了偏向锁,但我们可以通过-XX:UesBiaseLocking来启用它。
2.4 instanceof的模式匹配(二次预览)
模式匹配是由 JEP 305 在 2017 年年中提出的,并在 2019 年末作为预览语言功能针对 JDK 14。
此 JEP 建议在 JDK 15 中重新预览该功能,相对于 JDK 14 中的预览没有变化。
示例还可参考1.1小节。
2.5 JEP 377:ZGC垃圾回收器(转正)
ZGC 通过 JEP 333 集成到 JDK 11 中,当时还是处于实验阶段。经过多个版本的迭代,ZGC在Java 15终于可以正式使用了,不过默认的垃圾回收器还是G1,可以通过下列启动参数使用:
java -XX:+useZGC className
2.6 JEP 378:文本块(转正)
JEP 355 于 2019 年 6 月作为预览功能针对 JDK 13。
对 JDK 13 的反馈建议,在 JDK 14 中应该再次预览文本块,并添加两个新的转义序列。
对 JDK 14 的反馈表明,文本块在 JDK 15 中已经成为正式特性,没有进一步的更改。
2.7 Shenandoah垃圾回收器"转正"
Shenandoah垃圾回收器由 JEP 189 集成到 JDK 12 中(实验特性),经过几个版本迭代,在Java 15成为正式特性,不过默认的垃圾回收器还是G1,可以用java -XX:+UseShenandoahGC className启用。
以下类容来自Java 12:
Java 12引入Shenandoah垃圾回收器,一个专门用来处理大堆的低延迟垃圾回收器,性能几乎和ZGC相同(目标是99.9%的暂停时间小于10ms),不同的是ZGC是openJDK开发的,Shenandoah则是由RedHat开发的。
Shenandoah使用了一种用于并发压缩堆时维护对象引用的技术(布鲁克斯指针)。这种技术允许收集器在压缩堆时并行地移动对象,而不必暂停应用程序,这就允许Shenandoah能够在应用线程运行的同时进行垃圾回收,从而减少停顿,还有最重要的一点是暂停时间于堆大小无关,无论是200M或者200G的堆,暂停时间都一样。
2.8 JEP 383:外部内存访问 API(第二个孵化器)
参见1.8小节。
2.9 JEP 384:Records(二次预览)
Records由 JEP 359 于 2019 年年中提出,并于 2020 年初在 JDK 14 中作为预览功能提供。
此 JEP 建议在 JDK 15 中重新预览该功能,以合并基于反馈的改进,并支持 Java 语言中其他形式的本地类和接口。
Java 15仅作了细微调整,详情请参考1.3小节。
相关文章:

Java 14Java 15新特性概述
一、Java 14 发布于2020年3月17日。Java 14主要新特性如下: JEP 305:Pattern Matching for instanceof (Preview)instanceof 的模式匹配(预览) JEP 358:Helpful NullPointerExceptions 有用的 NullPointerExceptions…...

流量特征随机ua修改
作为一个蓝队吗喽,总是能看见因为ua头特征而直接被拦截的ip,当然了还有些是通过X-Forwarded-For被拦截的(X-Forwarded-For:fofa.info,不拦你才怪), 主要是通过python的mitmproxy和fake_useragent两个模块进行实现,代码量极低 fr…...

CSP-S 2024 提高级 第一轮(初赛) 阅读程序(3)
【题目】 CSP-S 2024 提高级 第一轮(初赛) 阅读程序(3) 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn 1000000 5; 7 const int P1 998…...

如何在 Rust 中通过 Rumqttc 实现 MQTT 通信
Rust 简介 Rust 是一门系统级编程语言,以其卓越的性能、并发能力以及内存安全特性著称。Rust 由 Mozilla 推出,目标是在现代软件开发中提供一种安全高效的编程语言。其设计旨在提供安全、并发和高效的编程体验,同时保持开发效率和代码质量不…...

广东高校建设AIGC实验室时需要注意哪几个关键点?
随着人工智能技术的飞速发展,特别是生成式人工智能(AIGC)在各行各业中的广泛应用,它已经成为推动新一轮科技革命和产业变革的关键力量。教育部等相关部门近年来也高度重视人工智能领域的人才培养工作,强调要加快推动高…...

设计模式-PIMPL 模式
PIMPL(Pointer to IMPLementation),又称Opaque Pointer模式或编译防火墙,是一种在C中广泛应用的编程技术。其核心思想是将类的实现细节从公共接口中分离出来,通过指向实现类的指针来访问类的具体功能。这种模式在提高代…...

Docker部署MongoDB教程
嘿,大家好!今天我在三丰云免费服务器上进行了一次激动人心的MongoDB部署测试。这款免费云服务器1核CPU、1G内存、10G硬盘、5M带宽,是不错的免费服务器选择。 首先,让我们简要介绍一下使用到的Docker和MongoDB软件。Docker是一个开…...

堆排序易错点
1.建堆和调整堆(插入和删除) 建堆和调整堆的过程是不一样的: 建堆 从非终端节点编号的结点开始依次建立大根堆,例如: 拿第2个图说,首先比较-1,7,从中选一个小的,即“-1”…...

安卓13长按电源按键直接关机 andriod13不显示关机对话框直接关机
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 有些设备需要在长按电源键的时候,直接关机。不需要弹出对话框进行询问。 2.问题分析 过滤电源按键,需要在系统里面处理的话,那么我们需要熟悉android的事件分发,然后再…...

React学习笔记(四)——React 组件生命周期
目录 1. 生命周期-概览 2. 生命周期-挂载阶段 3. 生命周期-更新阶段 4. 生命周期-卸载阶段 5. setState扩展-发现问题 6. setState扩展-更多用法 7. setState扩展-异步 1. 生命周期-概览 了解react类组件生命周期整体情况 大致步骤: 什么是生命周期React类组…...

PHP的guzzlehttp/guzzle库在碰到各种异常时的场景
PHP的guzzlehttp/guzzle库在碰到各种异常时的场景 结论: 经过测试得知 在http状态码为1xx, 2xx, 3xx时, 会在111处输出返回 在http状态码为4xx, 5xx时, 会在222处被捕获 在目标服务不可达或其他异常时会在333处被捕获 测试过程: 用其他程序写个接口, 实现输入什么状态码就返…...

多机部署,负载均衡-LoadBalance
文章目录 多机部署,负载均衡-LoadBalance1. 开启多个服务2. 什么是负载均衡负载均衡的实现客户端负载均衡 3. Spring Cloud LoadBalance快速上手使用Spring Cloud LoadBalance实现负载均衡修改IP,端口号为服务名称启动多个服务 负载均衡策略自定义负载均衡策略 LoadBalance原理…...

Hadoop安装与配置
一、Hadoop安装与配置 1、解压Hadoop安装包 找到hadoop-2.6.0.tar.gz,将其复到master0节点的”/home/csu”目录内,解压hadoop [csumaster0 ~]$ tar -zxvf ~/hadoop-2.6.0.tar.gz 解压成成功后自动在csu目录下创建hadoop-2.6.0子目录,可以用cd hadoo…...

一个自制的比较low的刷题软件
一个自制的比较low的刷题软件 一、背景 工作中往往涉及一些考试,比如阿里云ACP认证,华为GAUSS认证、软考等,应对这些考试的时候,我们往往是先看书后刷题(当然也有直接刷题的大神,毕竟考试,懂的…...

【Java 集合】List接口 —— ArrayList 与 LinkedList 详解
List接口继承自Collection接口,是单列集合的一个重要分支。 在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引(类似于数组中的元素角标)来访问集合中的指定元素。另外&…...

通信工程学习:什么是PNF物理网络功能
PNF:物理网络功能 PNF(Physical Network Function)即物理网络功能,是指支持网络功能的物理设备。以下是关于PNF的详细解释: 一、定义与特点 定义: PNF是网络设备厂商(如Cisco、华为、H3C等)通过专用硬件实体提供软件功能的设备。这些设备直接在物理服务器上运…...

Unity的Text组件中实现输入内容的渐变色效果
要在Unity的Text组件中实现输入内容的渐变色效果,默认的Text组件不直接支持渐变色。但是,你可以通过以下几种方式实现: ### 1. **使用Shader**来实现渐变效果 通过自定义Shader为Text组件创建一个渐变效果。这是一个常用的做法࿰…...

network-scripts目录下没有ens33文件的问题
作者:程序那点事儿 日期:2023/11/09 06:52 systemctl start NetworkManager #开启网络管理器nmcli con show #查看ens33网卡对应的是ifcfg-Wired_connection_3这个文件(网络管理器要开启,不然报错),或者根据…...

OpenHarmony(鸿蒙南向)——平台驱动指南【DAC】
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DAC(Digital to Analog Converter&…...

10.Lab Nine —— file system-下
Symbolic links 添加符号链接 1.添加有关symlink系统调用的定义声明,包括kernel/syscall.h, kernel/syscall.c, user/usys.pl 和 user/user.h. 2.添加新的文件类型T_SYMLINK到kernel/stat.h中,添加新的文件标识位O_NOFOLLOW到kernel/fcntl.h中 3.在ken…...

低代码中实现数据映射的必要性与方案
在数字化转型的浪潮中,低代码平台因其快速开发和灵活性而受到越来越多企业的青睐。然而,随着业务需求的复杂化,单纯依赖低代码工具往往难以满足企业在数据处理和业务逻辑上的要求。数据映射作为连接不同数据源和业务逻辑的桥梁,显…...

SpringBoot集成阿里easyexcel(一)基础导入导出
easyexcel主要用于excel文件的读写,可使用model实体类来定义文件读写的模板,对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…...

四元组问题
目录 问题描述 输入格式 输出格式 样例输入 样例输出 说明 评测数据规模 运行限制 原题链接 代码思路 问题描述 从小学开始,小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期,他遇到了一个非常有趣的问题&…...

如何用Prometheus监控禁用了Actuator的SpringBoot?
需求来源 prometheus监控微服务一般都是使用micrometer结合actuator来做: 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency> <d…...

使用TensorFlow实现一个简单的神经网络:从入门到精通
使用TensorFlow实现一个简单的神经网络:从入门到精通 在现代数据科学和机器学习领域,神经网络是一个非常重要的工具。TensorFlow 是一个开源的深度学习框架,由 Google 开发和维护,它使得构建和训练神经网络变得更加容易。本文将详细介绍如何使用 TensorFlow 实现一个简单的…...

应用DFX能力介绍
一、HarmonyOS生态DFX能力范围 围绕开发者,构建三方应用和设备从开发到维护全生命周期所必需、有竞争力、有特色的调试调优、定位、维护能力。 二、HarmonyOS DFX能力全集 三、DFX设计主要范围 1、HiLog 日志分类 日志常用命令 日志级别 日志规则 2、HiAppEvent 完…...

第三篇 第20章工程计价数字化与智能化
第三篇 工程计价 第20章 工程计价数字化与智能化 20.1 BIM在工程计价中的应用 20.1.1 BIM概述 1.定义 在建设工程及设施全生命周期内,对其物理特征和功能特征信息进行数字化表达,依次设计、施工、运营的过程和结果的总称。应由核心层、共享层、专业领域层、资源层四个概念层…...

成语700词(46~65组)
目录 46.熟悉、了解、知晓相关(15 个)47.很常见不奇怪(6 个)48.看法一致与否(10 个)49.从细节看全貌(10 个)50.看事情透彻(11 个)51.对事情的态度与评价(7 个)52.数量多与少(11 个)53.建筑相关(6 个)54.相同与不同(17 个)55.技艺精湛(10 个)56.与观看欣赏相…...

linux如何配置静态IP
文章目录 使用ip命令(临时配置)Debian/Ubuntu系统(使用netplan)CentOS/RHEL系统(使用nmcli或nmtui)使用nmcli(命令行界面)使用nmtui(文本用户界面)通过图形界…...

Dependency Check:一款针对应用程序依赖组件的安全检测工具
关于Dependency Check Dependency-Check 是一款软件组合分析 (SCA) 工具,可尝试检测项目依赖项中包含的公开披露的漏洞。它通过确定给定依赖项是否存在通用平台枚举 (CPE) 标识符来实现此目的。如果找到,它…...