严格来说,本文知识与数据结构联系不是很大,但是是博主学习数据结构的一个小插曲,所以把它放到了数据结构模块,请大家见谅。
JDK17语法新特性
yield关键字
yield关键字用于从case的代码块中返回值。
我们先看正常的switch
语句:
public static void main(String[] args) {
int ret = 0;
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
switch (str) {
case "one": ret = 1;
break;
case "two": ret = 2;
break;
default: ret = -1;
break;
}
System.out.println(ret);
}
yield
关键字:
public static void main(String[] args) {
int ret = 0;
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
ret = switch (str) {
case "one": yield 1;
case "two": yield 2;
default: yield -1;
};
System.out.println(ret);
}
- 需要一个变量接收返回值
- 不需要
break
语句 switch
的花括号结束要加;
yield
关键字可以换为->
指向符
public static void main(String[] args) {
int ret = 0;
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
ret = switch (str) {
case "one" -> 1;
case "two"-> 2;
default-> -1;
};
System.out.println(ret);
}
- 与
yield
关键字实现方案的改变在:将:yield
变为->
了
var关键字
var
关键字用于局部变量的类型推断
如下代码:
public static void main(String[] args) {
var a = 10;
var s = "hello";
}
使用了var
关键字,编译器会自动推断变量的类型,这么做可以简化代码(比如替代过长的泛型类名),同时保持了语言的强类型特性。
var
关键字不能声明:
1.字段
2. 方法参数
3. 方法返回类型var
声明的变量必须初始化,但是不能初始化为null
密封类(sealed、non-sealed、permits)
此处介绍三个关键字sealed
、non-sealed
和permits
说到密封类,我们第一时间想到final
关键字修饰类,表示:当前类不能被继承。这么做有个弊端,就是final
完全封锁了类,所有其他类都无法继承,针对这种情况,JDK17引入了新的关键字sealed
、permits
- 对于被
sealed
修饰的类,可以同时使用permits
来规定此类允许被哪些类继承 - 如果存在
permits
限制,则未被permits
允许的类型,没办法继承 - 被
sealed
修饰的类必须要有子类,并且其子类必须被final
或sealed
或non-sealed
修饰,满足一种情况,才不会报错,但要注意被sealed
修饰的情况。- 子类被
final
修饰:此子类为最终类,不能被任何类继承 - 子类被
sealed
修饰:与其父类一样,需满足sealed
的所有语法规定,如,该子类必须有子类, 有点像套娃 - 子类被
non-sealed
修饰:此子类为非密封类,可以被其他类继承,包括普通的类
- 子类被
//虽然无permits,但被sealed修饰,必须有子类,并且满足三种情况之一
sealed public class Base {
public int val;
}
//1. 被non-sealed修饰,允许被继承,包括普通的类
non-sealed class Child1 extends Base {
public int val;
}
class _Child1 extends Child1 {
public int val;
}
//2. 被final修饰,不能被继承了
final class Child2 extends Base {
public int val;
}
//3. 被sealed修饰,则它必须要有子类
sealed class Child3 extends Base {
public int val;
}
non-sealed class _Child3 extends Child3 {
public int val;
}
一旦有了permits
,如下图:
接口中的私有方法
之前的有关接口的博客介绍过,接口中的方法,默认都是public
、abstract
修饰,没有方法体,除非被default
或static
修饰,此时必须有方法体。
在Java8中,接口中可以有私有方法,即被private
修饰的方法,允许且必须有方法体,并且只能在该接口中使用,为其他默认方法或私有方法服务。
public interface ITest {
default void func1() {
func2();
func3();
System.out.println("default修饰的接口方法允许且必须有方法体");
}
static void func2() {
System.out.println("static修饰的接口方法允许且必须有方法体");
}
private void func3() {
func1();
func2();
System.out.println("private修饰的接口方法允许且必须有方法体,其只能在此接口中使用,为其他方法服务");
}
}
补充回顾:
- Java接口中由
default
修饰的方法的适用范围是所有实现了该接口的类,通过实现了接口的类的对象就可以调用 - Java接口中的由
static
修饰的方法,不能被接口本身直接使用,可以在静态区域通过接口名来访问
instanceof
我们知道,instanceof
用于检查一个对象是否属于某个类或接口的实例
常见代码如下:
if (obj instanceof String) {
String str = (String) obj;
...
}
instanceof
起到的作用:
- 判断是否为
String
类型; - 如果是,转成
String
类型; - 创建⼀个名为
str
的临时变量;
在JDK16中,使用模式匹配思想改进了instanceof
⽤法,可以做到以下优化效果(一步到位):
if (obj instanceof String str) {
}
obj
是否为String
类型,如果是创建临时变量str
完!下一篇正式开始数据结构正文。