【Java数据结构】JDK-17新增特性

一. 前⾔ 

从springboot3.0开始,已经不⽀持JDK8了。 从3.0开始,转变为JDK17。 

        官⽅维护的版本都是SpringBoot3.X的了,但是之前的版本也是可以⽤的,只是官⽅不再进⾏功能更新了.

综上所述,选⽤Java17,概括起来主要有下⾯⼏个主要原因:

1. JDK 17 是 LTS (⻓期⽀持版),可以免费商⽤到 2029 年。⽽且将前⾯⼏个过渡版(JDK 9-JDK 16)去其糟粕,取其精华的版本;
2. JDK 17 性能提升不少,⽐如重写了底层 NIO,⾄少提升 10% 起步;
3. ⼤多数第三⽅框架和库都已经⽀持,不会有什么⼤坑; 

二. ⼀些新增的特性

1 yield关键字

yield关键字,从Java13开始引⼊。yield关键字⽤于从case的代码块中返回值。
正常的switch语句:
 public static void main(String[] args) {
        String data = "one" ;
        int result = 0 ; // 接收数据的返回值
        switch (data) {
            case "one":
                result = 1 ; // 为result重新赋值
                break ;
            case "two":
                result = 2 ; // 为result重新赋值
                break ;
            default:
                result = -1 ; // 为result重新赋值
                break ;
        }
        System.out.println(result) ;
    }
简化后的switch:
  public static void main(String[] args) {
        String data = "one" ;
        int result = switch (data) {
            case "one"->1;
            case "two"->2;
            default->-1;
        };
        System.out.println(result) ;
    }
如果不想使⽤指向符-> 可以使⽤yield来代替:
  public static void main(String[] args) {
        String data = "one" ;
        int result = switch (data) {
            case "one" : yield 1;
            case "two": yield 2;
            default : yield -1;
        };
        System.out.println(result) ;
    }

2 var关键字

从Java10开始,var被引⼊
var name = "zhangsan";
var age = 10;
上述代码中,编译器会⾃动推断出name是⼀个String类型,age是⼀个int类型。

为什么使⽤var?
使⽤var可以使代码更简洁。有时候,类型名称可能会⾮常⻓,例如泛型。var就像是⼀个简化器,让你不必反复写出繁琐的类型名。
 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>>>();
    }
使⽤注意事项:
1. 不能使⽤var来声明字段
2. 不能使⽤var来声明⽅法参数
3. 不能使⽤var来声明⽅法返回类型
4. var声明变量必须初始化,但是不能初始化为null
class OrgCat {
    public var name;//error
    public var eat(var str) {//error
    }
}
    public static void main(String[] args) {
        var complexMap2 = 10;
        System.out.println(complexMap2);
        var str = null;//error
    }

3 空指针异常

         出现异常的具体⽅法和原因都⼀⽬了然。如果你的⼀⾏代码中有多个⽅法、多个变量,可以快速定位问题所在,如果是 JDK8,有些情况下真的不太容易看出来。

JDK8:

 

JDK17:

 

4 密封类

        密封类⼀般应⽤在类和接⼝中,对接⼝和类的实现和继承进⾏约束。主要使⽤的关键字是 final 。当这个类被 final 修饰了,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。
        JDK17提供了⼀个新的关键字: sealed .密封类除了可以被该关键字修饰,并且在声明末尾⽤
permits 表⽰要开放给哪些类型。
        下述代码Animal 为密封类,然后使⽤ permits 关键字,把继承权限开放 给了Dog 类
sealed class Animal permits Dog{
     public String name;
     public int age;
     public void eat() {
     System.out.println("eat()....");
}
//继承的类也要加上密封限制 non-sealed 表⽰不限制
non-sealed class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println(this.name+ "正在吃狗粮....");
        }
    }
重点总结:
1. sealed修饰的类必须要有⼦类
sealed class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println("eat()....");
    }
}
sealed class Dog extends Animal{//error
    @Override
    public void eat() {
        System.out.println(this.name+ "正在吃狗粮....");
    }
}
提⽰:Sealed class must have subclasses,此时Dog 被 sealed 修饰,那么Dog 必须要有⼦类!!

2. 使⽤ non-sealed 关键字修饰。表⽰不限制,任何类都可以继承。

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

使用sealed后面没有用permits则都可以继承,但继承的必须被non-sealed或者sealed或者final修饰,如果被sealed修饰则需要继续被继承(必须要有子类)


3. 未被 permits 允许的类型,则没办法继承
sealed class Animal permits Dog {
    public String name;
    public int age;
    public void eat() {
        System.out.println("eat()....");
    }
}
non-sealed class PetDog extends Animal {
}
正确做法可以改为:
 sealed class Animal permits Dog,PetDog {
    public String name;
    public int age;
    public void eat() {
        System.out.println("eat()....");
    }
}
non-sealed class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println(this.name+ "正在吃狗粮....");
    }
}
non-sealed class PetDog extends Animal {
}

4. 复杂的特殊写法
sealed class Animal permits Dog,Cat {
    public String name;
    public int age;
    public void eat() {
        System.out.println("eat()....");
    }
}
sealed class Cat extends Animal permits OrgCat{
}
non-sealed class OrgCat extends Cat {
}

5 接⼝中的私有⽅法

Java 8, 接⼝可以有默认⽅法。Java9之后,可以在接⼝内实现私有⽅法实现。
interface HelloService {
    public void sayHello();
    // 默认⽅法
    default void saySomething(){
        syaEngHello();
        sayHello();
    };
    // 私有⽅法
    private void syaEngHello(){
        System.out.println("Hello!");
    }
}

6 instanceof

⽐如以下常⻅的代码 :
if (obj instanceof String) {
        String str = (String) obj;
        ...
        }
上⾯的instanc of语法⼀共做了三件事:
1. 判断是否为String类型;
2. 如果是,转成String类型;
3. 创建⼀个名为str 的临时变量;
在JDK16中,使⽤模式匹配思想改进了instance of ⽤法,可以做到以下优化效果:
if (obj instanceof String str) {
// obj是否为String类型,如果是创建临时变量str
}

7 其他

其他还有很多未列举到的,⽐如:
1. ZGC-新⼀代垃圾回收器、G1垃圾回收器相关等等
2. record 类的使⽤
3. Stream API的部分改进
4. HttpClient 重写了,⽀持 HTTP2.0
5. ⽀持 List.of()、Set.of()、Map.of()和Map.ofEntries()等⼯⼚⽅法实例化对象
6. 等等更多的知识,等待着我们去探索!
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值