JDK17新增语法特性

前言

从springboot3.0开始,已经不支持JDK8,转变为JDK17
参考资料: 官方博客

新增语法特性

yield关键字

yield关键字从JDK13开始引入,yield关键字用于从case的代码块中返回值。
正常的switch语句:

public class Test {
    public static void main(String[] args) {
        String data = "ONE";
        int ret;
        switch(data){
            case "ONE":
                ret = 1;
                break;
            case "TWO":
                ret = 2;
                break;
            case "THREE":
                ret = 3;
                break;
            default:
                ret = -1;
                break;
        }
        System.out.println(ret);
    }
    //结果是:
    //1
}

简化后的switch语句

public class Test {
    public static void main(String[] args) {
        String data = "TWO";
        int ret = switch(data){
            case "ONE"->1;
            case "TWO"->2;
            case "THREE"->3;
            default->-1;
        };
        System.out.println(ret);
    }
    //结果是:
    //2
}

如果不想使用指向符->可以使用yield来代替:

public class Test {
    public static void main(String[] args) {
        String data = "TWO";
        int ret = switch(data){
            case "ONE" : yield 1;
            case "TWO" : yield 2;
            case "THREE": yield 3;
            default: yield -1;
        };
        System.out.println(ret);
    }
    //结果是:
    //2
}

var关键字

从java10开始,var被引入

var name = "zhangsan";
var age = 10;

上述代码中, 编译器会自动推断出name是一个String类型,age是一个int类型。
为什么使用var?
使用var可以使代码更简洁,有时候,类型的名称可能会非常长,例如泛型。var就像是一个简化器,让你不必反复写出繁琐的类型名。

public class Test {
    public static void main(String[] args) {
        Map<String, List<Map<Integer, String>>> complexMap = new HashMap<String,
                List<Map<Integer, String>>>();
        var complexMap2 = new HashMap<String, List<Map<Integer, String>>>();
    }
}   

使用注意事项:

  • 不能使用var来声明字段
  • 不能使用var来声明方法参数
  • 不能使用var来声明方法返回类型
  • var声明变量必须初始化,但是不能初始化为null
class Cat{
    public var name;    //error
    public var eat(var str){    //error

    }

    public static void main(String[] args) {
        var a = 1;
        System.out.println(a);
        
        var b = null;   //error
    }
}

密封类

密封类一般应用在类和接口中,对接口和类的实现和继承进行约束,主要使用的关键字是final,当这个类被final修饰了,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。
JDK17提供了一个关键字:sealed。密封类除了可以被该关键字修饰,并且在声明末尾使用permits表示要开放给哪些类型。
下述代码Animal为密封类,然后用permits关键字,把继承权限开放给Dog类

sealed class Animal permits Dog{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
//继承的类也要加上密封限制 non-sealed 表⽰不限制
non-sealed class Dog extends Animal{
    public void eat(String name){
        System.out.println(name + "正在吃狗粮");
    }
}

注意:

  • sealed修饰的类必须有子类
sealed class Animal permits Dog{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
sealed class Dog extends Animal{
    public void eat(String name){
        System.out.println(name + "正在吃狗粮");
    }
}
//编译器报错:Sealed class must have subclasses,此时Dog被sealed修饰,那么Dog必须要有子类
  • 使用non-sealed关键字修饰。表示不限制,任何类都可以继承。
sealed class Animal permits Dog{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
//继承的类也要加上密封限制 non-sealed 表⽰不限制
non-sealed class Dog extends Animal{
    public void eat(String name){
        System.out.println(name + "正在吃狗粮");
    }
}
  • 未被permits允许的类型,则没办法继承
sealed class Animal permits Dog{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
non-sealed class PetDog extends Animal{

}
//编译器报错:'PetDog' is not allowed in the sealed hierarchy

正确的做法可以改为:

sealed class Animal permits Dog,PetDog{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
non-sealed class Dog extends Animal{
    public void eat(String name){
        System.out.println(name + "正在吃狗粮");
    }
}
non-sealed class PetDog extends Animal{

}
  • 复杂的特殊写法:
sealed class Animal permits Dog,PetDog,Cat{
    public String name;
    public int age;
    public void eat(String name){
        System.out.println(name + "正在吃......");
    }
}
sealed class Cat extends Animal permits PetCat{
}
non-sealed class PetCat extends Cat{
}

接口中的私有方法

public interface IHelloService {
    public void sayHello();
    //默认方法
    default void saySomething(){
        sayHello();
        sayEngHello();
    }
    //私有方法
    private void sayEngHello(){
        System.out.println("Hello!");
    }
}

instanceof

比如以下常见的代码:

if(obj instanceof String){
	String str = (String)obj;
	...

上面的instanceof一共做了三件事:

  1. 判断是否为String类型;
  2. 如果是,转换成String类型;
  3. 创建一个名为str的临时变量;

在JDK16中,使用模式匹配思想改进了instanceof用法,可以做到以下优化效果:

if(obj instanceof String str){	//obj是否为String类型,如果是创建临时变量str
	
}

其他

还有很多,需要我们后续继续了解和学习

  • ZGC-新一代垃圾回收器、G1垃圾回收器相关等等
  • record类的使用
  • Stream API的部分改进
  • HttpClient重写了,支持HTTP2.0
  • 支持了List.of()、Set.of()、Map.of()和Map.ofEntries()等⼯⼚⽅法实例化对象
  • 等等…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值