不知不觉Java14已于3月17发布正式版,虽然我们大部分人还在用Java8,但是作为Java程序员还是有必要了解一下Java的发展趋势以及新的变化。虽然Java14不是LTS版本,但新的特性应该会延续到后续版本中。

语法层面新特性

一、instanceof的模式匹配

  使用instanceof关键字来判断对象的真实类型,可以不用强制转换了,从而减少冗余的代码

Object o = new Person("Tom", "18");
    
//老的方式
if(o instanceof Person) {
    Person p = (Person) o;
    System.out.println(p);
}
        
//java14实现方式
if(o instanceof Person p) {
    System.out.println(p);
}
public boolean test(Person person) {
    Object obj = new Person("Tom", "18");
    return obj instanceof Person p && person.equals(obj);
}

二、switch表达式

Java8中switch支持的类型有:byte char short int Byte Short Character Integer String  enum

Java12中支持返回值和 ->语法,Java13支持yield返回值,这两个版本只是预览版,Java14中正式发布switch表达式特性

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(1);
    case TUESDAY                -> System.out.println(2);
    case THURSDAY, SATURDAY     -> System.out.println(3);
    case WEDNESDAY              -> System.out.println(4);
}

//返回值
int i = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 1;
    case TUESDAY                -> 2;
    case THURSDAY, SATURDAY     -> 3;
    case WEDNESDAY              -> 4;
};

//使用yield返回值
int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        System.out.println("default");
        yield 2;
    }
};

、文本块

类似于Python和Groovy,方便编写多行的字符串字面量。

Java13中已引入作为预览特性,Java 14中做了改进,引入了两个新的转义序列。可以使用 \s 转义序列来表示一个空格,可以使用反斜杠 \ 来避免在行尾插入换行字符。

String text = """
    select t.* from test t \
    where t.a = 1 and t.b = 1\s\
    and exist (\s\
    select 1 from test1 t2 where t2.a = t.a and t2.b = t.b\s\
    )
""";
System.out.println(text);

 四、record

类似于Lombok的@Data注解,用于减少固定的模板代码。和枚举类型一样,记录也是类的一种受限形式,只用于存储数据,没有其它自定义的行为。

public record Person(String name, int age) {
    public static String address;
    
    public String getName() {
        return name;
    }
}

//反编译结果
public final class Person extends java.lang.Record {
    private final java.lang.String name;
    private final java.lang.String age;
    public static int a;

    public Person(java.lang.String name, java.lang.String age) { /* compiled code */ }

    public java.lang.String getName() { /* 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 */ }
}

1、record只能作用于类,且该类为final修饰,不能被继承。属性都是final修饰的,不能再被赋值,不能完全代替JavaBeans使用。

2、继承了java.lang.Record,不可以在继承其它类。

3、可以定义静态属性、静态或实例方法、构造函数。

五、NullPointerException 错误推断

虚拟机参数里面加上-XX:+ShowCodeDetailsInExceptionMessages,可以显示空指针发生时显示明确的诊断信息,有助于查找问题

 

JVM层面新特性

一、删除CMS垃圾收集器

CMS用于老年代垃圾收集,使用的是标记清除算法。

会产生内存碎片,导致无法提供连续的分配空间分配大对象。无法处理浮动垃圾,并发收集对CPU资源比较敏感。

二、弃用ParallelScavenge + SerialOld GC组合

三、macOS和Windos上支持ZGC

四、针对G1的NUMA感知内存分配