15都要来了,JDK14新特性你都了解吗?
点击蓝色“程序职场”关注我哟
加个“星标”,天天和你一起进步
https://blog.csdn.net/momo57l/article/details/105543683
简介
本次的Jdk14版本将带来16个增强方案
除此之外,Jdk14版本修复了共1986项问题,其中大部分由Oracle工作人员完成
增强
JEP 305 - Pattern Matching for instanceof (Preview)
JEP 343 - Packaging Tool (Incubator)
JEP 345 - NUMA-Aware Memory Allocation for G1
JEP 349 - JFR Event Streaming
JEP 352 - Non-Volatile Mapped Byte Buffers
JEP 358 - Helpful NullPointerExceptions:
JEP 359 - Records (Preview)
JEP 361 - Switch Expressions
JEP 362 - Deprecate the Solaris and SPARC Ports
JEP 363 - Remove the Concurrent Mark Sweep (CMS) Garbage Collector
JEP 364 - ZGC on macOS
JEP 365 - ZGC on Windows
JEP 366 - Deprecate the ParallelScavenge + SerialOld GC Combination
JEP 367 - Remove the Pack200 Tools and API
JEP 368 - Text Blocks (Second Preview)
JEP 370 - Foreign-Memory Access API (Incubator)
环境
Jdk14:https://www.oracle.com
Idea2020.1:https://www.jetbrains.com
使用
JEP 305:instanceof的模式匹配:通过消除对通用样板代码的需求,提高了开发人员的生产率,并允许使用更简洁的类型安全的代码
在Jdk之前的版本中,使用instanceof模式匹配的时候需要手动进行强制转换成需要的类型。在该版本中可以直接在后面跟上变量名,接下来不用强转就能直接使用该变量
Object obj = "hello 14";
// Jdk之前版本
if (obj instanceof String) {
String str = (String) obj;
System.out.println("str length:" + str.length());
} else {
System.out.println("obj not string.");
}
// Jdk14版本
if (obj instanceof String str) {
System.out.println("str length:" + str.length());
} else {
System.out.println("obj not string.");
}
JEP 343:打包工具:此孵化器工具为开发人员提供了一种打包Java应用程序的方式,以便以平台特定的格式进行分发
这些格式包括Windows上的msi和exe,MacOS上的pkg和dmg,以及Linux上的deb和rpm
JEP 345:G1的NUMA-Aware内存分配:此功能提高了非均匀内存访问(NUMA)系统上G1垃圾收集器的整体性能
NUMA技术:https://www.ibm.com/developerworks/cn/linux/l-numa/index.html
JEP 349:JFR事件流:此功能公开了JDK Flight Recorder(JFR)数据以进行连续监视,这将简化各种工具和应用程序对JFR数据的访问
HotSpot VM使用JFR发出500多个数据点,除了解析日志文件外,大多数其他方法无法使用。如果要使用数据,用户必须开始记录,停止记录,将内容转储到磁盘,然后解析记录文件。这对于应用程序概要分析非常有效,其中通常一次记录至少一分钟的数据,但不适用于监视目的。而在新特性中可以公开JFR发出的数据,用于持续监控
JEP 352:非易失性映射字节缓冲区:使用非易失性存储器时,此功能为JDK添加了文件映射模式
对FileChannel API进行了扩展,允许创建MappedByteBuffer实例。非易失性内存能够持久化数据,因此可以利用该特性来改进性能
JEP 358:实用的NullPointerExceptions:通过精确描述哪个变量为null以及其他有用信息,提高了 NullPointerExceptions的可用性。这将提高开发人员的生产率,并提高许多开发和调试工具的质量
目前该特性需要使用-XX:+ShowCodeDetailsInExceptionMessages参数开启
String str = null;
System.out.println(str.length());
/**
* Jdk之前版本异常输出:
* Exception in thread "main" java.lang.NullPointerException
* at DemoNull.main(DemoNull.java:9)
*/
/**
* Jdk14版本异常输出:
* Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is null
* at DemoNull.main(DemoNull.java:9)
*/
JEP 359:Records:此预览功能提供了一种紧凑的语法,用于声明保存浅层不变数据的类。从表面上看,此功能大大减少了此类中的样板代码,但最终目的是更好地允许将数据建模为数据
在之前的Jdk版本中,如果我们要申明一个final实体类,需要手动写构造器、getter、equals、hashCode、toString等方法。而现在,只需要使用record关键字,一行代码即可搞定,申明之后将自动获得一个构造器、getter、equals、hashCode、toString方法。在record申明的类中也可以定义其他构造器、方法、静态方法和静态属性。record申明的类不能再用abstract修饰。record申明的类不能继承其他的类。
/**
* @author liujiazhong
*/
public final class Order {
private final Long orderId;
private final String orderCode;
public Order(Long orderId, String orderCode) {
this.orderId = orderId;
this.orderCode = orderCode;
}
public Long getOrderId() {
return orderId;
}
public String getOrderCode() {
return orderCode;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Order)) return false;
Order order = (Order) o;
return Objects.equals(getOrderId(), order.getOrderId()) &&
Objects.equals(getOrderCode(), order.getOrderCode());
}
public int hashCode() {
return Objects.hash(getOrderId(), getOrderCode());
}
public String toString() {
return "Order{" +
"orderId=" + orderId +
", orderCode='" + orderCode + '\'' +
'}';
}
}
/**
* @author liujiazhong
*/
public record RecordOrder(Long orderId, String orderCode) {
}
// 测试
Order order1 = new Order(1001L, "TEST1001");
RecordOrder order2 = new RecordOrder(1002L, "TEST1002");
System.out.println(order1);
System.out.println(order2);
System.out.println(order1.getOrderCode());
System.out.println(order2.orderCode());
// 结果
Order{orderId=1001, orderCode='TEST1001'}
RecordOrder[orderId=1002, orderCode=TEST1002]
TEST1001
TEST1002
// 可以定义其他信息
public record RecordOrder(Long orderId, String orderCode) {
public static final String TYPE = "online";
public RecordOrder() {
this(1003L, "TEST1003");
}
public static void printType() {
System.out.println(TYPE);
}
public void printOrderCode() {
System.out.println(orderCode);
}
}
JEP 361:Switch表达式:它允许将switch用作语句或表达式,简化了日常的编码,这是JDK 12和JDK 13中的预览功能
String str = "A";
// Jdk之前的版本
switch (str) {
case "A":
System.out.println("A");break;
case "B":
System.out.println("B");break;
default:
System.out.println("default");
}
// Jdk12之后
switch (str) {
case "A", "C" -> System.out.println("A || C");
case "B" -> System.out.println("B");
default -> System.out.println("default");
}
// yield用于返回值
int score = switch (str) {
case "A" -> 90;
case "B" -> 80;
default -> {
System.out.println("default");
yield 70;
}
};
System.out.println(score);
JEP 362:弃用Solaris和SPARC端口:在将来的发行版中将其删除
放弃对这些端口的支持将使OpenJDK社区中的贡献者能够加速新功能的开发,这些新功能将推动平台向前发展
JEP 363:删除并发标记扫描(CMS)垃圾回收器
CMS垃圾收集器在两年前已过时,并且自JDK 6起已成为CMS的后继产品的G1已成为默认GC,并且已经在许多情况下大规模使用。我们还看到引入了两个新的收集器,ZGC(Jdk11)和Shenandoah(Open Jdk12),同时对G1进行了许多改进 。CMS存在几个弊端,比如会产生内存碎片,并发清理后导致用户线程可用的空间不足,因为是并发清理,所以对CPU资源非常敏感,而且无法处理浮动垃圾
详细信息:https://openjdk.java.net/jeps/363
/**
* 在Jdk14中通过-XX:+UseConcMarkSweepGC选项尝试使用CMS的话会得到下面的警告信息
* Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0
*/
List<String> list = new ArrayList<>();
while (true) {
list.add("a");
}
JEP 364,JEP 365:ZGC on macOS and Windows:尽管大多数需要ZGC的用户也需要基于Linux的环境的可伸缩性,但是在Windows和macOS中也经常需要部署和测试它。还有某些桌面应用程序将从ZGC功能中受益。因此,ZGC功能已移植到Windows和macOS
ZGC与Shenandoah目标非常相似,在尽可能对吞吐量影响不大的前提下,实现在任意堆内存大小下都可以把停顿时间限制在10毫秒以内。ZGC收集器是一款基于Region内存布局的,(暂时)不设分代,使用了读屏障、染色指针和内存多重映射等技术来实现可并发标记-压缩算法,首要目标是低延迟
详细信息:https://openjdk.java.net/jeps/364
上图引用自:The Z Garbage Collector - An Introduction
/**
* -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
*/
List<String> list = new ArrayList<>();
while (true) {
list.add("a");
}
JEP 366:弃用ParallelScavenge + SerialOld GC组合,该组合很少使用,但需要大量维护工作
详细信息:https://openjdk.java.net/jeps/366
/**
* 使用-XX:+UseParallelGC -XX:-UseParallelOldGC或者-XX:-UseParallelOldGC参数启用组合后提示以下信息
* Java HotSpot(TM) 64-Bit Server VM warning: Option UseParallelOldGC was deprecated in version 14.0 and will likely be removed in a future release.
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while (true) {
list.add("a");
}
}
JEP 367:删除Pack200工具和API:将删除java.util.jar软件包中的pack200和unpack200工具以及Pack200 API。这些工具和API 已在Java SE 11中弃用
删除原因:https://openjdk.java.net/jeps/367
JEP 368:文本块:在Java 首次将文本块作为预览功能(JEP 355)引入时,收到反馈后,添加了两个新的转义序列。该功能增强了Java程序中用非Java语言编写代码的字符串的可读性
// Jdk之前的版本
String sql1 = "select\n" +
"\t*\n" +
"from\n" +
"\tord_order_item ooi\n" +
"left join ord_order oo on\n" +
"\tooi.order_id = oo.id\n" +
"where\n" +
"\too.order_code = 'TEST1001'\n" +
"order by\n" +
"\too.id desc";
// 三引号表示文本块
String sql2 = """
select
*
from
ord_order_item ooi
left join ord_order oo on
ooi.order_id = oo.id
where
oo.order_code = 'TEST1001'
order by
oo.id desc
""";
// 新增“\s”表示空格,“\”表示去除换行
String sql3 = """
select
*
from
ord_order_item ooi
left join ord_order oo on
ooi.order_id = oo.id
where
oo.order_code = 'TEST1001'
order by\s\
oo.id desc
""";
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);
JEP 370:外部存储器访问API:此孵化器模块引入了一个API,以允许Java程序安全有效地访问Java堆之外的外部存储器
详细信息:https://openjdk.java.net/jeps/370
补充
祝看完这篇文章的小伙伴收获满满!点个在看吧~~~三连来一波~~~
▎好文推荐
点击☞
点击☞
点击☞(敏捷)
▎我的开源项目
点击☞