一、引入
从springboot3.0开始,已经不支持JDK8了,从3.0开始,转变为JDK17
了解详情点击官方博客链接:https://spring.io/blog/2022/01/20/spring-boot-3-0-0-m1-is-now-available?spm=a2c6h.12873639.article-detail.24.766d46b40LM1IVhttps://spring.io/blog/2022/01/20/spring-boot-3-0-0-m1-is-nowavailable?spm=a2c6h.12873639.article-detail.24.766d46b40LM1IVhttps://spring.io/blog/2022/01/20/spring-boot-3-0-0-m1-is-nowavailable?spm=a2c6h.12873639.article-detail.24.766d46b40LM1IV
二、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 后的 switch :
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) ; }
三、var关键字
从Java10开始,var 关键字被引入
public static void main(String[] args) {
var name = "zhangsan";
var age = 10;
}
// 在这段代码中,编译器会⾃动推断出name是⼀个String类型,age是⼀个int类型
使用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 }
四、空指针异常
出现异常的具体方法和原因都是一目了然
如果你的一行代码中有多个方法、多个变量,可以快速定位问题所在
如果是 JDK1.8,有些情况下真的不太容易看出来
JDK8:
JDK17:
五、密封类
密封类一般应用在类和接口中,对接口和类的实现和继承进行约束,主要使用的关键字是 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{
@Override // Sealed class must have subclasses,此时Dog 被 sealed 修饰,那么Dog 必须要有⼦类!!
public void eat() {
System.out.println(this.name+ "正在吃狗粮....");
}
}
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 + "正在吃狗粮...."); } }
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 { }
六、接口中的私有方法
Java8,接口可以有默认方法
Java9之后,可以在接口内实现私有方法
示例:
interface HelloService { public void sayHello(); // 默认⽅法 default void saySomething(){ syaEngHello(); sayHello(); }; // 私有⽅法 private void syaEngHello(){ System.out.println("Hello!"); } }
七、instanceof
示例:
if (obj instanceof String) { String str = (String) obj; ... }
上面的instancof语法做了三件事:
1. 判断是否为 String 类型
2. 如果是,转成 String 类型
3. 创建⼀个名为 str 的临时变量
在JDK16中,使用模式匹配思想改进了 instanceof 用法,可以做到以下优化效果:
if (obj instanceof String str) { // obj是否为String类型,如果是创建临时变量str
}