新项目决定用 JDK 17了
大家好,我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态。
文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面。
最近在调研 JDK 17,并且试着将之前的一个小项目升级了一下,在测试环境跑了一段时间。最终,决定了,新项目要采用 JDK 17 了。
JDK 1.8:“不是说好了,他发任他发,你用 Java 8 吗?”
不光是我呀,连 Spring Boot 都开始要拥护 JDK 17了,下面这一段是 Spring Boot 3.0 的更新日志。
Spring Boot 3.0 requires Java 17 as a minimum version. If you are currently using Java 8 or Java 11, you'll need to upgrade your JDK before you can develop Spring Boot 3.0 applications.
Spring Boot 3.0 需要 JDK 的最低版本就是 JDK 17,如果你想用 Spring Boot 开发应用,你需要将正在使用的 Java 8 或 Java 11升级到 Java 17。
选用 Java 17,概括起来主要有下面几个主要原因:
1、JDK 17 是 LTS (长期支持版),可以免费商用到 2029 年。而且将前面几个过渡版(JDK 9-JDK 16)去其糟粕,取其精华的版本;
2、JDK 17 性能提升不少,比如重写了底层 NIO,至少提升 10% 起步;
3、大多数第三方框架和库都已经支持,不会有什么大坑;
4、准备好了,来吧。
拿几个比较好玩儿的特性来说一下 JDK 17 对比 JDK 8 的改进。
密封类
密封类应用在接口或类上,对接口或类进行继承或实现的约束,约束哪些类型可以继承、实现。例如我们的项目中有个基础服务包,里面有一个父类,但是介于安全性考虑,值允许项目中的某些微服务模块继承使用,就可以用密封类了。
没有密封类之前呢,可以用 final
关键字约束,但是这样一来,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。
密封类用关键字 sealed
修饰,并且在声明末尾用 permits
表示要开放给哪些类型。
下面声明了一个叫做 SealedPlayer
的密封类,然后用关键字 permits
将集成权限开放给了 MarryPlayer
类。
public sealed class SealedPlayer permits MarryPlayer {
public void play() {
System.out.println("玩儿吧");
}
}
之后 MarryPlayer
就可以继承 SealedPlayer
了。
public non-sealed class MarryPlayer extends SealedPlayer{
@Override
public void play() {
System.out.println("不想玩儿了");
}
}
继承类也要加上密封限制。比如这个例子中是用的 non-sealed
,表示不限制,任何类都可以继承,还可以是 sealed
,或者 final
。
如果不是 permits 允许的类型,则没办法继承,比如下面这个,编译不过去,会给出提示 "java: 类不得扩展密封类:org.jdk17.SealedPlayer(因为它未列在其 'permits' 子句中)"
public non-sealed class TomPlayer extends SealedPlayer {
@Override
public void play() {
}
}
空指针异常
String s = null;
String s1 = s.toLowerCase();
JDK1.8 的版本下运行:
Exception in thread "main" java.lang.NullPointerException
at org.jdk8.App.main(App.java:10)
JDK17的版本(确切的说是14及以上版本)
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "s" is null
at org.jdk17.App.main(App.java:14)
出现异常的具体方法和原因都一目了然。如果你的一行代码中有多个方法、多个变量,可以快速定位问题所在,如果是 JDK1.8,有些情况下真的不太容易看出来。
yield关键字
public static int calc(int a,String operation){
var result = switch (operation) {
case "+" -> {
yield a + a;
}
case "*" -> {
yield a * a;
}
default -> a;
};
return result;
}
换行文本块
如果你用过 Python,一定知道Python 可以用 'hello world'
、"hello world"
、''' hello world '''
、""" hello world """
四种方式表示一个字符串,其中后两种是可以直接支持换行的。
在 JDK 1.8 中,如果想声明一个字符串,如果字符串是带有格式的,比如回车、单引号、双引号,就只能用转义符号,例如下面这样的 JSON 字符串。
String json = "{\n" +
" \"name\": \"古时的风筝\",\n" +
" \"age\": 18\n" +
"}";
从 JDK 13开始,也像 Python 那样,支持三引号字符串了,所以再有上面的 JSON 字符串的时候,就可以直接这样声明了。
String json = """
{
"name": "古时的风筝",
"age": 18
}
""";
record记录类
类似于 Lombok 。
传统的Java应用程序通过创建一个类,通过该类的构造方法实例化类,并通过getter和setter方法访问成员变量或者设置成员变量的值。有了record关键字,你的代码会变得更加简洁。
之前声明一个实体类。
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用 Record
类之后,就像下面这样。
public record User(String name) {
}
调用的时候像下面这样
RecordUser recordUser = new RecordUser("古时的风筝");
System.out.println(recordUser.name());
System.out.println(recordUser.toString());
输出结果
Record 类更像是一个实体类,直接将构造方法加在类上,并且自动给字段加上了 getter 和 setter。如果一直在用 Lombok 或者觉得还是显式的写上 getter 和 setter 更清晰的话,完全可以不用它。
G1 垃圾收集器
JDK8可以启用G1作为垃圾收集器,JDK9到 JDK 17,G1 垃圾收集器是默认的垃圾收集器,G1是兼顾老年代和年轻代的收集器,并且其内存模型和其他垃圾收集器是不一样的。
G1垃圾收集器在大多数场景下,其性能都好于之前的垃圾收集器,比如CMS。
ZGC
从 JDk 15 开始正式启用 ZGC,并且在 JDK 16后对 ZGC 进行了增强,控制 stop the world 时间不超过10毫秒。但是默认的垃圾收集器仍然是 G1。
配置下面的参数来启用 ZGC 。
-XX:+UseZGC
可以用下面的方法查看当前所用的垃圾收集器
JDK 1.8 的方法
jmap -heap 8877
JDK 1.8以上的版本
jhsdb jmap --heap --pid 8877
例如下面的程序采用 ZGC 垃圾收集器。
其他一些小功能
1、支持 List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法实例化对象;
2、Stream API 有一些改进,比如 .collect(Collectors.toList())
可以直接写成 .toList()
了,还增加了 Collectors.teeing()
,这个挺好玩,有兴趣可以看一下;
3、HttpClient
重写了,支持 HTTP2.0,不用再因为嫌弃 HttpClient 而使用第三方网络框架了,比如OKHTTP;
升级 JDK 和 IDEA
安装 JDK 17,这个其实不用说,只是推荐一个网站,这个网站可以下载各种系统、各种版本的 JDK 。地址是 https://adoptium.net/。
还有,如果你想在 IDEA 上使用 JDK 17,可能要升级一下了,只有在 2021.02
版本之后才支持 JDK 17。
如果觉得还不错的话,给个推荐吧!
公众号「古时的风筝」,Java 开发者,专注 Java 及周边生态。坚持原创干货输出,你可选择现在就关注我,或者看看历史文章再关注也不迟。长按二维码关注,跟我一起变优秀!
新项目决定用 JDK 17了的更多相关文章
- AndroidStudio创建新项目报错
创建新项目自动执行时报错: Failed to import new Gradle project: failed to find Build Tools revision 17.0.0 Consul ...
- Android新项目GBSS:第1篇 搭建开发环境
最近接手一个Android新项目,之前也没做过这方面的开发,算是边学边干,这两天看了一下Android开发的书,大致入门了一点,今天把所需要的软件都下了下来,准备开工,先列一下开发环境: 所有的软件都 ...
- IDEA | 更改idea打开新项目默认配置
背景 使用过idea的童鞋应该都发现,用idea打开一个新项目,总是需要重新配置一遍,它会使用系统默认配置,例如maven.JDK等设置. 解决方案 IDEA其实有个设置是可以更改新项目的默认配置,大 ...
- IntelliJ 更改项目使用的 JDK 版本
在当前使用的 IntelliJ 中的 JDK 版本为 1.8,如何修改 IntelliJ 使用的 JDK 版本为 1.11 呢? 你可以在 IntelliJ 中进行修改. 选择 File 后,然后选择 ...
- swift开发新项目总结
新项目用swift3.0开发,现在基本一个月,来总结一下遇到的问题及解决方案 1,在确定新项目用swift后,第一个考虑的问题是用纯swift呢?还是用swift跟OC混编 考虑到新项目 ...
- 用Kotlin开发Android应用(II):创建新项目
这是关于Kotlin的第二篇.各位高手发现问题,请继续“拍砖”. 原文标题:Kotlin for Android(II): Create a new project 原文链接:http://anton ...
- 在AndroidStudio v1.2.0中导入或增加新项目或工程(导入第三方类库或工程)
以下说明基于AndroidStdudio版本v1.2 由于AndroidStudio项目止录与Eclipse中的Worksapce在意义上的改变,所以导入新包或建立新项目时并不和以前那样了. 下面是我 ...
- 【Cocos2d-x for WP8 学习整理】(1)创建一个新项目
喜大普奔 10.1假期之前看到了一个很振奋的消息,就是随着Cocos2d-x 2.2的发布,WP8/WIN8有史以来第一次的合并到主版本了. 之前 V2 ...
- cocos2d-x 3.2 创建新项目问题
cocos2d-x 3.2 执行cocos2d-x\tools\cocos2d-console\console下的cocos2d.py,输入相应的参数即可创建一个新的项目,具体参数网上介绍一大堆,就不 ...
- Myeclipse中导入新项目报叹号
Myeclipse中导入新项目报红色叹号 原因是导入项目中,有的jar路径不对, 在上图中,先把报错的jar移除,之后将JRE开头的那个library移除,最后点击add Library,选择jre. ...
随机推荐
- 智能工厂的ERP和MES之间的区别?
无论在哪里,ERP(Enterprise Resource Planning,企业资源计划)和MES(Manufacturing Execution System,即制造执行系统)系统都不是同样的东西 ...
- Vue+vant移动端处理弹窗不能滑动问题
自己在做项目开发时,使用vantUI组件,在项目中遇到了弹窗组件里面当内容过多时,会出现滚动卡顿或者不能滚动问题,开始一直以为是自己的样式写的有问题,检查下来才发现并不是,而是弹窗组件的问题,于是找到 ...
- P7962 [NOIP2021] 方差 (DP)
题目的意思就是可以交换差分数组,对答案进行化简:n∑ai2−(∑ai)2 ,再通过手玩分析可得最优解的差分数组一定是单谷(可以感性理解一下),因此我们将差分数组排序,依次加入,每次可以选择加在左边 ...
- Vue3解决ElementPlus Drawer或弹出对话框不生效的问题
第一时间检查你是否还在使用 :visible.sync="drawer" 来绑定事件框的隐藏和显示,vue3.0 已经更改为通过 v-model 来绑定事件框的显示与隐藏.
- 14.MongoDB系列之配置分片
1. 启动服务器 1.1 启动配置服务器 配置服务器是集群的大脑,保存着关于每个服务器包含哪些数据的所有元数据,因此,必须首先创建配置服务器. 由于资源限制,在同一机器上启动三个进程 # mkdir ...
- js排序的基础原理理解
在了解数组排序前,我们先了解下如何交换两个数字的位置 假设我们有这么一个数组 var arr=[1,2,3] 我们想交换1和3两个的位置我们该如何做呢? 最简单的肯定是手动赋值,如下 var arr= ...
- 如何使用IDEA创建一个简单的java工程?
文章目录 1.创建新工程 1.1 新建项目 1.2 在src目录下创建package 1.3 在包下创建类 2.编写代码.运行项目 2.1 编写代码 2.2 运行结果 3.开心的从eclipse转移到 ...
- Kubeadm部署k8s单点master
Kubeadm部署k8s单点master 1.环境准备: 主机名 IP 说明 宿主机系统 master 10.0.0.17 Kubernetes集群的master节点 CentOS 7.9 node1 ...
- Programiranje 方法记录
[COCI2017-2018#3] Programiranje 题面翻译 题目描述 Little Leticija正在准备编程考试.虽然她已经解决了很多任务,但还有一个任务尚未解决,所以她正在向你寻求 ...
- redux中间件
Redux 中间件 什么是中间件? 中间件本质上就是一个函数,Redux允许我们通过中间件的方式,扩展和增强Redux应用程序,增强体现在对action处理能力上,之前的计数器与弹出框案例中.acti ...