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…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...