JDK17新增语法特性
- 前言
- 新增语法特性
- yield关键字
- var关键字
- 密封类
- 接口中的私有方法
- instanceof
- 其他
前言
从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一共做了三件事:
- 判断是否为String类型;
- 如果是,转换成String类型;
- 创建一个名为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()等⼯⼚⽅法实例化对象
- 等等…