首页 > 其他分享 >SpringBoot 3.0最低版本要求的JDK 17,这几个新特性不能不知道

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

时间:2023-09-14 15:46:25浏览次数:44  
标签:instanceof Java SpringBoot 17 JDK switch 3.0 String

最近,有很多人在传说 SpringBoot要出3.0的版本了,并且宣布不再支持 Java 8,最低要求是 Java 17了。

其实,早在2021年9月份,关于 Spring Framework 6.0的消息出来的时候,Spring 官方就已经明确了不会向下兼容,最低的 JDK 版本是 JDK 17。

image

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

image

这一次 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" +     "        <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`;     """;

看起来就比较直观,清爽了。

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 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势必要被应用到生产环境中。

以上这些特性,大多数都是对开发比较友好的,有机会的话可以应用起来。

标签:instanceof,Java,SpringBoot,17,JDK,switch,3.0,String
From: https://www.cnblogs.com/jeecg158/p/17702597.html

相关文章

  • SpringBoot中@ConfigurationProperties和@PropertySource的区别
    @ConfigurationProperties用于将主配置文件(application.properties或者“application.yml”)中的属性,映射到实体类中对应的属性。意思就是把主配置文件中配置属性设置到对应的Bean属性上。只需要写明prefix,如下,prefix是sever,就会自动将application文件中以sever开头的配置一一注......
  • 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览本篇是《支持JDK19虚拟线程的web框架》系列的中篇,前文咱们体验了有虚拟线程支持的web服务,经过测试,发现性能上它与其他两种常见web架构并无明显区别,既然如此,还有......
  • springboot智能3D人体导医系统源码
    智能3D人体导医系统源码医院智能导诊系统是在医疗中使用的引导患者自助就诊挂号,在就诊的过程中有许多患者不知道需要挂什么号,要看什么病,通过智能导诊系统,可输入自身疾病的症状表现,或选择身体部位,在经由智慧导诊系统多维度计算,精准推荐科室,引导患者挂号就诊,实现科学就诊,不再担心挂......
  • SpringBoot单体用户登录校验
    一、概述要做一个有私有空间的单体的SpringBoot项目,用户的权限校验是必须得。需要指定哪些接口需要权限才能访问,哪些接口不需要权限就能访问。目标:1.用户登录、注册不需要权限校验,获取用户信息需要权限校验2.获取用户信息通过token来获取(从token中取......
  • ubuntu安装jdk
    卸载检查是否安装:dpkg--list|grep-ijdk移除openjdk包:apt-getpurgeopenjdk*卸载OpenJDK相关包:apt-getpurgeicedtea-*openjdk_*再次检查是否卸载成功:dpkg--list|grep-ijdk安装sudoaptinstallopenjdk-8-jdk配置java_homevi/etc/profile写入:exportJA......
  • 2023.09.13
      今天学习了java关于类与对象的知识,包括方法,对象,构造函数,继承,封装的学习,以及this关键字的学习1、程序    为了完成现实世界的某个功能或者任务而编写的一系列有序代码的集合2、面向对象编程--oop用对象的方式来模拟现实世界---软件3、对象  对象是类的实例4......
  • springboot集成CAS客户端实现单点登录
    pom中引入依赖<!--cas--><dependency><groupId>org.jasig.cas.client</groupId><artifactId>cas-client-core</artifactId><version>3.6.2</version></dependen......
  • Spring高手之路14——深入浅出:SPI机制在JDK与Spring Boot中的应用
    1.SPI解读:什么是SPI?  SPI (ServiceProviderInterface)是一种服务发现机制,它允许第三方提供者为核心库或主框架提供实现或扩展。这种设计允许核心库/框架在不修改自身代码的情况下,通过第三方实现来增强功能。JDK原生的SPI:定义和发现:JDK的SPI主要通过在META-INF/services/目......
  • springboot 整合 nacos 实现配置文件统一管理 和 服务注册
    1.我使用的是 nacos-server-1.4.1 直接启动nacos没有配置数据库那些.\startup.cmd-mstandalone2.启动后在nacos中创建命名空间配置文件 注意命名空间的id我是自己定义的还有group到时候配置错了服务又不会报错只是会读取不到3.springboot配置 server-addr......
  • Springboot RocketMQ整合—官方原版
    Doker 技术人自己的数码品牌Doker官网:Doker多克一、添加maven依赖:<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>${RELEASE.VERSION}</version></dependen......