Java14上手

Java14上手

Scroll Down

话不多说,开整。

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 是个好东西,实在是追新利器,但是老生常谈的问题是,技术并不是越新越好,自己玩玩可以随便去玩,若想用于生产就得慎重考虑了。