大家好,我是风筝,公众号「古时的风筝」,专注于 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了的更多相关文章

  1. AndroidStudio创建新项目报错

    创建新项目自动执行时报错: Failed to import new Gradle project: failed to find Build Tools revision 17.0.0 Consul ...

  2. Android新项目GBSS:第1篇 搭建开发环境

    最近接手一个Android新项目,之前也没做过这方面的开发,算是边学边干,这两天看了一下Android开发的书,大致入门了一点,今天把所需要的软件都下了下来,准备开工,先列一下开发环境: 所有的软件都 ...

  3. IDEA | 更改idea打开新项目默认配置

    背景 使用过idea的童鞋应该都发现,用idea打开一个新项目,总是需要重新配置一遍,它会使用系统默认配置,例如maven.JDK等设置. 解决方案 IDEA其实有个设置是可以更改新项目的默认配置,大 ...

  4. IntelliJ 更改项目使用的 JDK 版本

    在当前使用的 IntelliJ 中的 JDK 版本为 1.8,如何修改 IntelliJ 使用的 JDK 版本为 1.11 呢? 你可以在 IntelliJ 中进行修改. 选择 File 后,然后选择 ...

  5. swift开发新项目总结

    新项目用swift3.0开发,现在基本一个月,来总结一下遇到的问题及解决方案   1,在确定新项目用swift后,第一个考虑的问题是用纯swift呢?还是用swift跟OC混编      考虑到新项目 ...

  6. 用Kotlin开发Android应用(II):创建新项目

    这是关于Kotlin的第二篇.各位高手发现问题,请继续“拍砖”. 原文标题:Kotlin for Android(II): Create a new project 原文链接:http://anton ...

  7. 在AndroidStudio v1.2.0中导入或增加新项目或工程(导入第三方类库或工程)

    以下说明基于AndroidStdudio版本v1.2 由于AndroidStudio项目止录与Eclipse中的Worksapce在意义上的改变,所以导入新包或建立新项目时并不和以前那样了. 下面是我 ...

  8. 【Cocos2d-x for WP8 学习整理】(1)创建一个新项目

    喜大普奔                         10.1假期之前看到了一个很振奋的消息,就是随着Cocos2d-x 2.2的发布,WP8/WIN8有史以来第一次的合并到主版本了. 之前 V2 ...

  9. cocos2d-x 3.2 创建新项目问题

    cocos2d-x 3.2 执行cocos2d-x\tools\cocos2d-console\console下的cocos2d.py,输入相应的参数即可创建一个新的项目,具体参数网上介绍一大堆,就不 ...

  10. Myeclipse中导入新项目报叹号

    Myeclipse中导入新项目报红色叹号 原因是导入项目中,有的jar路径不对, 在上图中,先把报错的jar移除,之后将JRE开头的那个library移除,最后点击add Library,选择jre. ...

随机推荐

  1. Node.js(三)Lodash

    npm init -y(初始化项目) npm i --save lodash(引入lodash) const _=require("lodash"); let stus=[ {id ...

  2. docker搭建yapi接口文档系统、Idea中上传接口、在线调用

    一.前言 在我们后端开发中,必不可少的是接口的交接,有很多种方式,常见的就是swagger,不过这个侵入性太强了.还有就是接口文档的框架,比如今天小编带大家一起搭建的yapi,在公司还是挺常见的! 今 ...

  3. TCP和UDP的区别与联系以及网络字节序和主机字节序的转换函数实践

    TCP和UDP的区别 TCP是一个面向连接的.可靠的.基于字节流的传输层协议. 而UDP是一个面向无连接的传输层协议. 具体来分析,和 UDP 相比,TCP 有三大核心特性: 面向连接:所谓的连接,指 ...

  4. 大数据技术之HBase原理与实战归纳分享-下

    @ 目录 整合Phoenix 定义 为何要使用 安装 SHELL操作 表的映射 简易JDBC示例 二级索引 二级索引配置文件 全局索引 包含索引 本地索引(local index) HBase与 Hi ...

  5. 【编程学习】MATLAB

    目录 一.MATLAB基础 1. 学会完成MATLAB的安装与启动 1.1 软件包下载 1.2 安装步骤 2. 矩阵的基本操作与运算 2.1 矩阵的简单输入与操作 2.2 矩阵的基本运算 2.2.1 ...

  6. Linux-->vi和vim编辑器的基本操作

    vim编辑器介绍 vi或者vim就是对linux下的文本进行编辑的一种编辑器比如说a.cpp文件这种 Linux会内置vi文本编辑器 Vim可以简单的认为vi的增强版 Linux是区分大小写的! 用法 ...

  7. Java学习之路:HelloWorld

    2022-10-08 16:13:57 HelloWorld   1. 随便新建一个文件夹,存放代码   2. 新建一个Java文件 文件后缀名为.java hello.java 注意:系统没有显示后 ...

  8. 20220729 - DP训练 #2

    20220729 - DP训练 #2 时间记录 \(8:00-8:10\) 浏览题面 \(8:10-8:50\) T1 看题想到了建树,从每一个点遍历,若能遍历每一个点,则可以获胜 快速写完之后,发现 ...

  9. docker gitlab迁移 备份 部署 搭建以及各种问题

    当前环境 服务器A 服务器B ubuntu docker gitlab(版本一致) docker安装gitlab 由于考虑到gitlab 包含了⾃身的nginx.数据库.端⼝占⽤等等因数,这⾥使⽤的是 ...

  10. Unexpected token u in JSON at position 0

    文章目录 1.1 错误原因: 1.2 解决思路: 1.1 错误原因: 因为JSON.parse()不能解析字符串中的undefined 出错的结果:某一行的这个字段的值为空,就会报错,整个表格都显示不 ...