写点什么

SpringBoot 3.0 最低版本要求的 JDK 17,这几个新特性不能不知道!

  • 2022 年 6 月 27 日
  • 本文字数:4677 字

    阅读完需:约 15 分钟

最近,有很多人在传说 SpringBoot 要出 3.0 的版本了,并且宣布不再支持 Java 8,最低要求是 Java 17 了。其实,早在 2021 年 9 月份,关于 Spring Framework 6.0 的消息出来的时候,Spring 官方就已经明确了不会向下兼容,最低的 JDK 版本是 JDK 17。


2022 年,Spring Framework 6.0 和 SpringBoot 3.0 都会推出,在此之前,Java 社区很坚挺,一直是"新版任你发,我用 Java 8",不管新版本怎么出,很少有人愿意升级。


这一次,Spring 直接来了个大招,跨过 JDK 8-16,直接升级到 JDK 17 ,不知道会对 Java 生态产生怎样的影响。


为什么是 Java 17 这么多新版本的 JDK,而且 2022 年还会推出 JDK 18 和 JDK 19,为什么 Spring 选择了 JDK 17 呢。主要是因为他是一个 LTS 版本,所谓 LTS,是 Long Term Support,也就是官方保证会长期支持的版本。从 JDK 诞生到现在,还在长期支持的版本主要有 JDK 7、JDK 8 、JDK 11 以及 JDK 17


这一次 Spring 直接跨越了 JDK 11,升级到 JDK 17,主要的考虑应该是因为 JDK 17 有更多的新特性支持。


接下来我们介绍几个新特性,这些新特性都是我们开发者息息相关的,或者说是会影响我们写代码的。


JDK 17 支持的新特性这里所谓的新特性,不只是 JDK 17 中新增的,而是 JDK 17 和 JDK 8 相比,新增的特性。本地变量类型推断在 Java 10 之前版本中,我们想定义定义局部变量时。我们需要在赋值的左侧提供显式类型,并在赋值的右边提供实现类型:MyObject value = new MyObject();


在 Java 10 中,提供了本地变量类型推断的功能,可以通过 var 声明变量:var value = new MyObject();


本地变量类型推断将引入“var”关键字,而不需要显式的规范变量的类型。其实,所谓的本地变量类型推断,也是 Java 10 提供给开发者的语法糖。虽然我们在代码中使用 var 进行了定义,但是对于虚拟机来说他是不认识这个 var 的,在 java 文件编译成 class 文件的过程中,会进行解糖,使用变量真正的类型来替代 var(详细信息可以参考:我反编译了 Java 10 的本地变量类型推断)Switch 表达式在 JDK 12 中引入了 Switch 表达式作为预览特性。并在 Java 13 中修改了这个特性,引入了 yield 语句,用于返回值。而在之后的 Java 14 中,这一功能正式作为标准功能提供出来。在以前,我们想要在 switch 中返回内容,还是比较麻烦的,一般语法如下:int i;


switch (x) {
case "1":
i=1;
break;
case "2":
i=2;
break;
default:
i = x.length();
break;
}
复制代码


在 JDK13 中使用以下语法:int i = switch (x) {


    case "1" -> 1;
case "2" -> 2;
default -> {
int len = args[1].length();
yield len;
}
};
复制代码


或者 int i = switch (x) {


    case "1": yield 1;
case "2": yield 2;
default: {
int len = args[1].length();
yield len;
}
};
复制代码


在这之后,switch 中就多了一个关键字用于跳出 switch 块了,那就是 yield,他用于返回一个值。和 return 的区别在于:return 会直接跳出当前循环或者方法,而 yield 只会跳出当前 switch 块。Text BlocksJava 13 中提供了一个 Text Blocks 的预览特性,并且在 Java 14 中提供了第二个版本的预览。text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。我们以前从外部 copy 一段文本串到 Java 中,会被自动转义,如有一段以下字符串:<html>


  <body>
<p>Hello, world</p>
</body>
</html>
复制代码


将其复制到 Java 的字符串中,会展示成以下内容:"<html>\n" +


"    <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
复制代码


即被自动进行了转义,这样的字符串看起来不是很直观,在 JDK 13 中,就可以使用以下语法了:"""


<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
复制代码


使用“”“作为文本块的开始符和结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。如常见的 SQL 语句:String query = """


    SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
复制代码


看起来就比较直观,清爽了。RecordsJava 14 中便包含了一个新特性:EP 359: Records,Records 的目标是扩展 Java 语言语法,Records 为声明类提供了一种紧凑的语法,用于创建一种类中是“字段,只是字段,除了字段什么都没有”的类。通过对类做这样的声明,编译器可以通过自动创建所有方法并让所有字段参与 hashCode()等方法。这是 JDK 14 中的一个预览特性。使用 record 关键字可以定义一个记录:record Person (String firstName, String lastName) {}


record 解决了使用类作为数据包装器的一个常见问题。纯数据类从几行代码显著地简化为一行代码。(详见:Java 14 发布了,不使用”class”也能定义类了?还顺手要干掉 Lombok!)封闭类在 Java 15 之前,Java 认为"代码重用"始终是一个终极目标,所以,一个类和接口都可以被任意的类实现或继承。但是,在很多场景中,这样做是容易造成错误的,而且也不符合物理世界的真实规律。例如,假设一个业务领域只适用于汽车和卡车,而不适用于摩托车。在 Java 中创建 Vehicle 抽象类时,应该只允许 Car 和 Truck 类扩展它。通过这种方式,我们希望确保在域内不会出现误用 Vehicle 抽象类的情况。为了解决类似的问题,在 Java 15 中引入了一个新的特性——密闭。想要定义一个密闭接口,可以将 sealed 修饰符应用到接口的声明中。然后,permit 子句指定允许实现密闭接口的类:public sealed interface Service permits Car, Truck {


}
复制代码


以上代码定义了一个密闭接口 Service,它规定只能被 Car 和 Truck 两个类实现。与接口类似,我们可以通过使用相同的 sealed 修饰符来定义密闭类:public abstract sealed class Vehicle permits Car, Truck {


}
复制代码


通过密闭特性,我们定义出来的 Vehicle 类只能被 Car 和 Truck 继承。instanceof 模式匹配 instanceof 是 Java 中的一个关键字,我们在对类型做强制转换之前,会使用 instanceof 做一次判断,例如:if (animal instanceof Cat) {


    Cat cat = (Cat) animal;
cat.miaow();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
复制代码


Java 14 带来了改进版的 instanceof 操作符,这意味着我们可以用更简洁的方式写出之前的代码例子:if (animal instanceof Cat cat) {


    cat.miaow();
} else if(animal instanceof Dog dog) {
dog.bark();
}
复制代码


我们都不难发现这种写法大大简化了代码,省略了显式强制类型转换的过程,可读性也大大提高了。switch 模式匹配基于 instanceof 模式匹配这个特性,我们可以使用如下方式来对对象 o 进行处理:static String formatter(Object o) {


    String formatted = "unknown";
if (o instanceof Integer i) {
formatted = String.format("int %d", i);
} else if (o instanceof Long l) {
formatted = String.format("long %d", l);
} else if (o instanceof Double d) {
formatted = String.format("double %f", d);
} else if (o instanceof String s) {
formatted = String.format("String %s", s);
}
return formatted;
}
复制代码


可以看到,这里使用了很多 if-else,其实,Java 中给我们提供了一个多路比较的工具,那就是 switch,而且从 Java 14 开始支持 switch 表达式,但 switch 的功能一直都是非常有限的。在 Java 17 中,Java 的工程师们扩展了 switch 语句和表达式,使其可以适用于任何类型,并允许 case 标签中不仅带有变量,还能带有模式匹配。我们就可以更清楚、更可靠地重写上述代码,例如:static String formatterPatternSwitch(Object o) {


    return switch (o) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> o.toString();
};
}
复制代码


可以看到,以上的 switch 处理的是一个 Object 类型,而且 case 中也不再是精确的值匹配,而是模式匹配了。


总结以上,我们介绍了几个从 JDK 9 开始,一直到 JDK 17 中的几个能够改变我们写代码的方式的新特性。其实,众多的版本中,还有一些其他的特性及优化,我们没有在这里一一展开。大家感兴趣的可以到 JDK 官网查看各个版本的新功能介绍。随着 Spring Framework 6 和 SpringBoot 3.0 的推出,相信会有一些公司在新项目中采用新版本,那么 JDK 17 势必要被应用到生产环境中。以上这些特性,大多数都是对开发比较友好的,有机会的话可以应用起来。


图片影响了几十万名 Java 开发者的“Java 工程师成神之路”系列文章,相信作为 Javaer 的你肯定在网络上刷到读到过 N 次,很多人可能不知道作者 Hollis 是谁,但却都熟知这份“Java 工程师成神之路”。


在上市的这一个月的时间里,这本书,不仅一度冲上了京东计算机与互联网图书榜第一名,竟然还冲上了科技图书榜的第一名。



关于内容


这本书是《Java 工程师成神之路》系列丛书的第一本——基础篇,主要定位是帮助大家巩固基础的,书中囊括了我认为一个高级开发工程师需要掌握的所有的 Java 核心知识。


里面的大部分内容来源于以下几个方面:


1、日常工作中遇到的一些线上问题的经验总结;如为什么不能修改 serialVersionUID、为什么接口返回值中不能使用枚举。


2、平常面试中我会问的一些高频技术问题;如为什么 HashMap 要引入红黑树、如何在泛型是 String 的 List 中存放 Integer 对象。


3、我平常自己学习的一些笔记;如为什么 FastJson 频繁曝出序列化漏洞、有了 UTF-8 为什么还需要 GBK


4、工作中的一些好的代码实践;如为什么我不建议使用声明式事务、如何通过自定义注解写出优秀的代码


这本书是基于 JDK 17 编写的,其中不仅涵盖了新版本 JDK 的一些重要特性,也对一些历史版本的一些改动、变化等等做了详尽的阐述,如 JDK 6 中 substring 的内存泄漏问题、JDK 7 中 switch 是如何实现对 String 的支持的、JDK 8 的中 Stream 如何优雅使用、各个版本中的 HashMap 的优化过程等等。


还介绍了 JDK 9 中的模块化技术、JDK 10 中的本地变量类型推断、JDK 13 中的 text block、JDK 14 中的 record 类型、以及 JDK 16 – JDK 17 中的模式匹配等等。


这本书和其他 Java 基础类书籍最大的区别就是里面都是干货。书中没有那些概念性的描述、也没有那些无用的代码示例。更多的是通俗易懂的解读、底层原理的分析等。可以说没有任何废话。。。



关于彩蛋


在书籍刚刚出版的时候,我给大家说这本书中有一个彩蛋,现在可以告诉大家这个彩蛋是什么了。


用出版社的老师们的话来说,这真是史无前例的。



这是一份我自己总结的 Java 工程师知识地图,他有 70cm*100cm 这么大,里面囊括了一份完完整整的知识体系,方便大家进行对照和参考。


如果你想知道 Java 开发都需要会哪些知识。如果你想构建自己的知识体系。如果你想知道自己还有哪些东西不会。如果你想知道自己当前处于哪个阶段。


那这份知识体系,一定不能错过。


购书福利


最后给广大粉丝的优惠肯定不能少!!!


大家可以通过下方的二维码,或者点击阅读原文,直达京东下单购买《深入理解 Java 核心技术:写给 Java 工程师的干货笔记(基础篇)》一书。


5 折优惠,原价 138 元,附赠一份全栈的 Java 工程师知识地图!


现在到手价只需 69 元!


转发文章并留言,小编从留言中精选 5 名幸运粉丝,免费包邮送出一份“Java 工程师知识地图”助你全面掌握 Java 技术栈!



用户头像

还未添加个人签名 2019.10.21 加入

还未添加个人简介

评论

发布
暂无评论
SpringBoot 3.0最低版本要求的JDK 17,这几个新特性不能不知道!_博文视点Broadview_InfoQ写作社区