当前JDK的版本已经到了23了,不过最近的LTS版本是21,刚好最近准备把直播侧serverless应用的JVM环境升级到java21(目前是11),在升级前对21的特性做一个简单的了解和熟悉,下面是个人熟悉过程中的笔记,大家可以按照每一节特性中的代码自己在本地run下,可以更快地做个了解。
JDK的版本其实最近几年开始,已经是6个月一个版本了,LTS版本大概差不多间隔4-6个版本(不定),每次升级,都会有比较多的迭代,但是主要还是集中在几个方面:1. 新特性的支持,其实主要还是面向编写和阅读的自然语言化,做的新特性的提供或者语法糖的封装,突出易懂易用;2. 内部核心实现的性能或者能力的提升,感知比较多的是gc,或者是内部的hotspot的能力等;3. bugfix,漏洞修复等。
LTS版本还是值得去了解,有条件的话也是比较推荐在生产环境去做使用的,因为不管是上述哪个方面带来的提升,对开发以及系统运维来说,都是属于易得的红利。
介绍
▐ JEP
JEP是Java Enhancement Proposal的简称,JEP的提出到生效也需要一个过程,分别是:
1. Draft(草稿)阶段:需要明确提议的动机、描述、目标和非目标(nongoals)、风险等;
2. Submission(提交)阶段:该阶段会给该提议生成一个唯一的标识,叫JAB number;
3. Review(审核)阶段:OpenJDK社区中和该提议比较相关的stakeholder会参与review,主要是看下这个提议对于Java的发展是否是必要、合理;
4. Sponsorship(赞助)阶段:这里主要是要有个开发团队去承接这个JEP的开发、测试和集成工作,该阶段还不需要实际投入开发;
5. Candidate Status(候选)阶段:进入到该阶段说明整个JEP完成立项,并且价值和作用得到了充分认同,然后是要等待在哪个版本去做试验接入;
6. Targeted(锁定版本)阶段:这个阶段已经为该JEP指定了一个JDK的版本,那需要把JEP对应的内容进行开发、测试;
7. Integrated(集成)阶段:将JEP对应的代码集成到具体版本的JDK源码中,刚集成到JDK源码中的特性一般都是preview状态,通常都需要至少1个版本迭代周期才能变成可被正常使用的状态,处于preview状态的JEP,只能被试验性使用,不能被应用到生产环境,因为功能或者说特性可能在下一个版本中就会发生变化;
8. Released(发布)阶段:该特性可以面向整体java开发者做使用,我们平时能用上的特性都属于这个范畴。
▐ SDKman
推荐一款比较不错的本地的管理各类语言版本的工具,SDKman,安装也很简单,可以进行不同版本的jdk的下载以及本地的环境切换;简单安装如下,一些命令可以参见 https://sdkman.io/
curl -s "https://get.sdkman.io" | bash
特性解读
▐ 1. Feature:Unnamed Classes and Instance Main Methods (Preview)
动机:这个特性java推出比较早了,当时没有觉得学习门槛高,因为其他当时比较流行的语言,门槛更高,而且更难读,但是随着一代代发展下来,新出来的语音在语法和表达上,更接近于NL,那一相比较,就显得java有点“年龄大,水土不服”。
//package main.java.org.example;
void main(String[] args) {
System.out.println("Hello world!");
}
TIPS:下文中特性后面括号带Preview的,都是前瞻的功能,需要使用的话得加上 --enable-preview:
javac --release 21 --enable-preview Main_TL.java
// 或在IDEA的VM参数中添加
--enable-preview
▐ 2. Feature: String Templates (Preview)
动机:更直观,简洁,方便维护,同时增加了值的验证和转换。
不少JEP都有Non-Goals,这个看看还是蛮有趣的,希望是什么,不希望成为什么,这个特性的Non-Goals可以体会下:
非目标方向
- 不是面向原有的字符串操作(+)提供语法糖;
- 不是为了弃用或移除传统上用于复杂或程序化字符串组合的 StringBuilder 和 StringBuffer 类。
public class StringTemplate {
static String anotherName = "Jiang";
public static void main(String[] args) {
String name = "Mario";
String number = "987689";
System.out.println(STR."name = \{name}, and number = \{number}, and anotherName = \{getAnotherName()}");
}
public static String getAnotherName() {
return anotherName;
}
}
▐ 3. Feature: Unnamed Patterns and Variables (Preview) & Record Patterns
(这两个feature比较关联的,就一起概述了)
动机:提升可读性,并且让程序员可以清楚知道哪些成员变量被使用,哪些成员变量未被使用,preview的功能就是可以使用下划线来代替不想使用到的record里面的成员。
package org.example;
import java.util.List;
/**
* 例子中sealed是java15给出的新特性,用于限制类继承,可以看做是枚举的扩展,java17中完善和标准化<br>
* record是java14引入的新特性,用于创建不可变类,java16的时候成为正式标准
*/
public class Unname