济南网站建设找大标,搜索引擎优化案例,移动网站和定制网站,微信商家联盟平台最近#xff0c;有很多人在传说 SpringBoot要出3.0的版本了#xff0c;并且宣布不再支持 Java 8#xff0c;最低要求是 Java 17了。
其实#xff0c;早在2021年9月份#xff0c;关于 Spring Framework 6.0的消息出来的时候#xff0c;Spring 官方就已经明确了不会向下兼…最近有很多人在传说 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 Blocks
Java 13中提供了一个Text Blocks的预览特性并且在Java 14中提供了第二个版本的预览。
text block文本块是一个多行字符串文字它避免了对大多数转义序列的需要以可预测的方式自动格式化字符串并在需要时让开发人员控制格式。
我们以前从外部copy一段文本串到Java中会被自动转义如有一段以下字符串 html body p Hello, world /p /body /html 将其复制到Java的字符串中会展示成以下内容 html\n body\n pHello, world/p\n /body\n /html\n;即被自动进行了转义这样的字符串看起来不是很直观在JDK 13中就可以使用以下语法了 html body pHello, world/p /body /html ;使用“”“作为文本块的开始符和结束符在其中就可以放置多行的字符串不需要进行任何转义。看起来就十分清爽了。
如常见的SQL语句 String query SELECT EMP_ID, LAST_NAME FROM EMPLOYEE_TB WHERE CITY INDIANAPOLIS ORDER BY EMP_ID, LAST_NAME; ;看起来就比较直观清爽了。
Records
Java 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 Integeri - String.format(int %d, i);case Longl - String.format(long %d, l);case Doubled - String.format(double %f, d);case Strings - String.format(String %s, s);default -o.toString();} ;}可以看到以上的switch处理的是一个Object类型而且case中也不再是精确的值匹配而是模式匹配了。
总结
以上我们介绍了几个从 JDK 9开始一直到 JDK 17中的几个能够改变我们写代码的方式的新特性。其实众多的版本中还有一些其他的特性及优化我们没有在这里一一展开。
大家感兴趣的可以到 JDK 官网查看各个版本的新功能介绍。
随着 Spring Framework 6 和 SpringBoot 3.0的推出相信会有一些公司在新项目中采用新版本那么 JDK 17势必要被应用到生产环境中。
以上这些特性大多数都是对开发比较友好的有机会的话可以应用起来。