话不多说,开整。
JEP 305 Instance模式匹配
String sentence = "Hello Java14";//假装sentence是个Object类型,可以当成参数传入
if(sentence instanceof String str){
System.out.println(str.length());
}else{
//....
}
控制台会输出 “Hello Java14” 这个字符串的长度 12。
需要注意的是,上述例子中,str的作用域仅限于if,如果对 if 括号里的表达式取反,则只有 else 中可以使用str
String sentence = "Hello Java14";
if(!(sentence instanceof String str)){
//这里不能使用str
//System.out.println(str.length());
}else{
System.out.println(str);
}
if(sentence instanceof String str && str.length() > 13){
//这里可以使用str
System.out.println(str.length());
}else{
//这里不可以使用str
System.out.println(str);
}
剩下的 ||、&、| 我就不一一试了,只需要记住,sentence instanceof String str 这句本身就包含了一个bool值,而且只有为true的时候,才会强转sentence并且赋值给str , 所以在这个条件可能为假的情况下,当然不能在后面继续调用,这很符合逻辑。
JEP 361 Switch表达式
使用一堆if 语句,我个人认为没有使用Swith来的简洁明了。这个可能会有争议,不过观点本来就会各异,可以不用,但是也得会,接下来康康Java14里的Switch是个什么样吧。
var score = "100";
var result = switch (score) {
case "100","90" -> "A";//90和100分之间的,被无情抛弃
case "80" -> "B";
default -> throw new IllegalStateException("Unexpected value: " + score);
};
System.out.println(result);
可以看到和原来相比,用箭头表达式代替了冒号,而且不需要 break ,并且switch 可以直接返回一个值,还是很方便的。
缺点是目前还不支持范围表达,没有某些语言 我忘记是哪个来着 的 .. 语法糖, 所以只能用 if 来了。
如果箭头右边的是语句块的话,类似这样,用 yield 赋值:
case 50 ->{
if(score > 50){
yield "C";
}else{
yield "D";
}
}
JEP 368 Text Blocks
String text =
"""
第一行
第二行
太香了
什么,kotlin早就有了?
哦
""";
for (String s : text.split("\n")) {
System.out.println(s);
}
再也不用烦人的 +"++"+ ,拼个短信模板,眼睛都要看瞎了,这个文本块和json、html、SQL语句简直是绝配,感觉干掉Mybatis的xml指日可待了。
JEP 359 record 类型
class作为实体类的时候确实太麻烦了,无聊的toString 和 hashCode,冗长的get set , 还有无聊的构造方法,所以才出现了Lombok和Builder模式,出现这些,其实本身就意味着原来做的还不够好,好在有了 record! 它来了它来了
record Person(String name,Integer age){}
javap看一下编译之后长啥样 :
static final class Person extends java.lang.Record {
private final java.lang.String name;
private final java.lang.String age;
public Person(java.lang.String name, java.lang.String age) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public java.lang.String name() { /* compiled code */ }
public java.lang.String age() { /* compiled code */ }
}
原来如此,编译器默默的在背后帮我们做了这么多事情,record 的特点是没有get、set 方法,提供了参数名作为调用,想使用时直接用person.name()、person.age() 就好了,需要注意的是:
- record 没有无参的构造方法
- 不能直接定义实例成员变量,可以定义静态成员变量
- 可以定义实例和静态方法
- 可以定义无参构造函数用于增强已有有参构造器
JEP 368 friendly NPE
万恶的NPE,以前的提示只有一个行号,如果是调用链的话,比如a.b.c()
, 根本不知道是a和b哪个出了问题,极大的锻炼了猜测能力,而现在只要运行的时候加一个 JVM 参数 -XX: +ShowCodeDetailsInExceptionMessages Npe
,就可以看到具体的提示了,这个太简单了,就不演示了。
JEP 343 Java 打包工具
jpackage 这个可以将 Java 程序打包成各平台的安装格式,比如MacOS的dmg、Linux的deb,rpm、Windows的msi和exe,不过好像局限性挺多的,不适合太复杂的程序,以后写个小服务啥的,直接打包运行,也不用羡慕Go了。
不过查了一会,也没查到这个打的 Hello World 安装包会有多大,而且会不会把 JRE 打包进去?
我看着繁琐的步骤,懒得去试了。
其他
JEP 是个好东西,实在是追新利器,但是老生常谈的问题是,技术并不是越新越好,自己玩玩可以随便去玩,若想用于生产就得慎重考虑了。