我还在生产玩 JDK7,JDK 15 却要来了!|新特性尝鲜

自从 JDK9 以后,每一年 3 月与 9 月 JDK 都会发布一个新的版本,而2020 年 9 月即将引来 JDK15。javascript

恰巧 IDEA 每四五个月会升级一个较大的版本,每次升级以后都会支持最新版本 JDK 引入的新功能。java

这几天升级了 IDEA,顺便体验了一下 JDK15 的新特性。shell

虽然我知道大家可能跟我同样JDK8 都还没用熟,可是无妨,看看新版本 JDK 来酸一下。编辑器

Text Blocks 最终定板

以前版本的 JDK,若是咱们须要插入 HTMLXMLSQLJSON 片断,很是麻烦,须要对里面符号进行各类转义。ide

因此我每次都会在其余编辑器将 HTML ,XML 等编辑好,而后直接复制到 IDEA 中,IDEA 自动会对这些字符转义。学习

每次复制进去就变成上图的效果,若是上面字符再多点,阅读起来就会更难,而且难以维护。优化

所幸 IDEA 提供了一个 Inject Language 功能,咱们能够在里面快速方便的编辑。idea

Java 开发者也关注到这个问题,他们在 JDK13 引入的一个新的预览特性「Text Blocks」,可使用三引号将复杂的字符串赋值,从而让咱们从各类转义中解脱出来,能够更加方便的编辑字符串。spa

这个功能在其余语言仍是比较常见的,好比 Python 等。.net

Text Blocks 新功能在 JDK14 再次以预览功能引入,最终在 JDK15 成为新版本的正式功能。

下面咱们来对比一下使用 Text Blocks 与以前区别:

Html

SQL

JS

Records (Second Preview)

JDK14 引入一个新的预览特性 record 语法,能够快速建立一个纯数据类,而且不用去生成 gettertoString 等。

使用下面的语法就能够快速建立一个数据类:

public record Point(int x,int y) {
}

JDK15 是 record 这个语法的第二次预览,这个版本增长一个新的功能 「local record」,能够在一个方法在快速建立一个类,以便于方法中业务逻辑计算。

在如下示例中,使用本地记录 MerchantSales 对商人和每个月销售额的汇总进行建模,使用此记录可提升如下流操做的可读性:

下面例子的中咱们新建一个类 MerchantSales,而后按照销售人员对每个月的销售额汇总排序。

List<Merchant> findTopMerchants(List<Merchant> merchants, int month) {
    // Local record
    record MerchantSales(Merchant merchant, double sales) {}

    return merchants.stream()
        .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
        .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales()))
        .map(MerchantSales::merchant)
        .collect(toList());
}

原先若是须要使用这种功能,咱们不得不建立一个内部类,后续可能不再会用到,使用 local record就解决这个尴尬的问题。

除了 local record 咱们还能够建立 local enums 以及 local interface

// local enums
public void organisePeople(List<Person> people) {
    enum Role {
        Employee, Customer, Both, None
    }
    HashMap<Role, List<Person>> peopleByRole = new HashMap<>();
    people.stream()
            .filter(Person::isCustomer)
            .forEach(person -> peopleByRole.computeIfAbsent(Role.Customer, role -> new ArrayList<>())
                    .add(person));
    // 其余业务逻辑

}
// local interface
public void localInterface() {
    interface MyInterface {
        void doSomething();
    }
    MyInterface testInterface = new MyInterface() {
        @Override
        public void doSomething() {
            System.out.println("Hello World!");
        }
    };
    // 其余业务逻辑

}

最后使用这个特性须要注意一点,local record , local enums ,local interface 建立都是一个局部变量,是不能被传递其余方法引用。

Pattern Matching for instanceof (Second Preview)

咱们应该都看到过下面这种代码:

if (obj instanceof String) {
    String str = (String) obj;
    // use str
}

上面代码意图很是简单,当 obj 对象是 String 类,就将其强制转换,而后进行其余业务操做。

这种写法,类型转换仍是比较繁琐,Pattern Matching for instanceof 这个新语法特性,能够帮咱们省略这种类型转换动做。这是一个在 JDK14 引入一个预览特性,JDK 15 开始第二次预览。

上面的代码使用 pattern matcher,就能够被修改以下:

if (obj instanceof String s) {
    s.contains("T");
} else {
    // 编译错误
    //s.contains("T");
}

另外若是在 IDEA 中还能够提示咱们将代码转化成 pattern matcher

你们应该都看过 Effective Java 这本神书吧,里面第八条关于 Equals 有一个例子:

使用 pattern matcher 咱们就可使用下面更加清晰的代码代替:

Sealed Classes (Preview)

Java 中一个正常普通类/接口容许被其余子类继承/实现,可是有时在平常开发中,咱们可能但愿只有特定的类才能继承扩展。

现有的 Java 语法中存在一些方法,能够限制子类扩展,好比说:咱们可使用 final 修饰类

public final class String

不过这样以后,咱们就没办法再继承这个类。

其次咱们能够限制的类的范围,好比说不使用 public 修饰类/接口,即便用 default 范围,这样只有同一个包才能继承/实现。

interface DefaultExample {
}

不过使用这种方式,又很尴尬,这个类就没法被其余包使用。

为了解决上述问题,JDK 15 引入一个新的预览特性 Sealed Classes,便可以限定类的扩展,也能够被外部使用。

public sealed class Shape
    permits Circle, Rectangle, Square {...}

使用 sealed 修饰以后,Shape 类只能被 CircleRectangleSquare继承,不再能被其余类继承。

同时 Shape 的子类存在一些限制,必须使用 final 修饰,代表这个类没法再被扩展:

public final class Circle extends Shape {...}

或者继续使用 sealed 表示子类只能被指定类继承:

public sealed class Rectangle extends Shape 
    permits TransparentRectangle, FilledRectangle {...}
public final class TransparentRectangle extends Rectangle {...}

又或者说使用 non-sealed 代表这个子类不限制子类扩展,能够被其余任何类扩展实现。

另外 sealed class 还能够跟上述 record 语法一块儿使用。

public sealed interface Expr
    permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {...}

public record ConstantExpr(int i)       implements Expr {...}
public record PlusExpr(Expr a, Expr b)  implements Expr {...}
public record TimesExpr(Expr a, Expr b) implements Expr {...}
public record NegExpr(Expr e)           implements Expr {...}

ZGC

ZGC(Z Garbage Collector) 这是一款在 JDK11 引入的的具备实验性质的低延迟的 GC 收集器。

这款 GC 收集器的但愿在尽量对吞吐量影响不大的前提下,实如今任意堆内存大小均可以把垃圾收集器的停顿时间限制在十毫秒之内的低延迟。

ZGC 通过这两三年的迭代优化,终于在 JDK15 中正式引入,标志着 ZGC 能够正式应用于生产应用。

JDK15 中默认虚拟机仍是 G1,若是须要使用 ZGC,须要在启动参数中加入以下参数:

-XX:+UseZGC command-line

最后

原本这篇文章是准备写下 IDEA 2020.2 新版本特性,顺带介绍一下 JDK15 新特性的。

但是没想到写着写着,JDK15 相关的篇幅就过长了,因此就单独拿出来了。

最后,最后,JDK 都发布到 15 了,而我却还在用 JDK 7 ,真是个悲伤的故事,逃了逃了!

我是楼下小黑哥,天天学习一点点,成长亿点点!!

参考连接

https://openjdk.java.net/proj...

欢迎关注个人公众号:程序通事,得到平常干货推送。若是您对个人专题内容感兴趣,也能够关注个人博客: studyidea.cn

相关文章
相关标签/搜索