在Java 14中引入了一个预览特性,即“模式匹配增强”(Pattern Matching for instanceof),这个特性在Java 16中继续作为预览特性,并在Java 17中成为正式特性。这个特性改进了instanceof的使用方式,允许在检查对象类型的同时进行类型转换,并且可以直接在条件表达式的结果中使用这个转换后的对象。
instanceof之前的写法
在Java 17之前,你需要使用传统的instanceof检查和显式的类型转换:
package com.morris.java17;
/**
* java17之前版本instance of的使用
*/
public class InstanceOfOldDemo {
public static void main(String[] args) {
Object obj = "Hello, World!";
if (obj instanceof String) {
String str = (String) obj;
System.out.println("Length: " + str.length());
} else {
System.out.println("Not a string");
}
}
}
instanceof模式匹配的使用
在Java 17及更高版本中,你可以这样使用instanceof模式匹配:
package com.morris.java17;
/**
* instance of模式匹配的使用
*/
public class InstanceOfDemo {
public static void main(String[] args) {
Object o1 = "Hello, World!";
if (o1 instanceof String str) {
// 直接使用str变量,无需强制类型转换
// str局部变量只能在这个if内使用,不能在else内使用
System.out.println("Length: " + str.length());
} else {
System.out.println("Not a string");
}
// 判断一个对象是不是字符串并且长度大于2个字符,中间只能是&&,不能是&或者||
Object o2 = "asr";
if (o2 instanceof String str && str.length() > 2) {
System.out.println("o2.length() > 2");
} else {
System.out.println("o2.length() <= 2");
}
Object o3 = "hello java";
//这里做的是取反运算
if (!(o3 instanceof String str)) {
System.out.println("o3 not a String");
// System.out.println(str);// 这里不能使用str
} else {
System.out.println(str);// 这里可以使用str
}
}
}
instanceof模式匹配只能在if、while、for等条件语句中使用。它不能用于switch语句(尽管Java 17引入了switch表达式的模式匹配,但这与instanceof模式匹配不同)。
使用instanceof模式匹配时,类型变量(如上面的str)的作用域仅限于if语句块内。
这个特性提高了代码的可读性和简洁性,避免了不必要的强制类型转换和可能的ClassCastException。
工作原理
反编译InstanceOfDemo的源码,可以发现编译后的代码是使用了强制类型转换。
package com.morris.java17;
public class InstanceOfDemo {
public InstanceOfDemo() {
}
public static void main(String[] args) {
Object o1 = "Hello, World!";
String o2;
if (o1 instanceof String) {
o2 = (String)o1;
System.out.println("Length: " + o2.length());
} else {
System.out.println("Not a string");
}
String o3;
label22: {
o2 = "asr";
if (o2 instanceof String) {
o3 = (String)o2;
if (o3.length() > 2) {
System.out.println("o2.length() > 2");
break label22;
}
}
System.out.println("o2.length() <= 2");
}
o3 = "hello java";
if (o3 instanceof String) {
String str = (String)o3;
System.out.println(str);
} else {
System.out.println("o3 not a String");
}
}
}