首页IT科技jdk1.8和1.7区别(新项目决定用 JDK 17了)

jdk1.8和1.7区别(新项目决定用 JDK 17了)

时间2025-04-29 07:13:51分类IT科技浏览3948
导读:大家好,我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态。...

大家好           ,我是风筝                 ,公众号「古时的风筝」      ,专注于 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, youll 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 及周边生态     。坚持原创干货输出                 ,你可选择现在就关注我           ,或者看看历史文章再关注也不迟                 。长按二维码关注,跟我一起变优秀!

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
php中的五种数据结构(php八大数据类型) javascript中的回调函数(JavaScript 回调函数属于闭包?)