Java14的新特性

Java语言特性系列

本文主要讲述一下Java14的新特性

版本号

java -version
openjdk version "14" 2020-03-17
OpenJDK Runtime Environment (build 14+36-1461)
OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

从version信息可以看出是build 14+36

特性列表

305:Pattern Matching for instanceof (Preview)

JDK14引入了preview版本的针对instanceof的模式匹配,其用法示例如下

    public boolean isBadRequestError(Exception ex) {
        return (ex instanceof HttpClientErrorException rce) &&
                HttpStatus.BAD_REQUEST == rce.getStatusCode();
    }

无需在自己进行类型强转

343:Packaging Tool (Incubator)

JDK14引入了jdk.incubator.jpackage.jmod,它基于JavaFX javapackager tool构建,目的在于创建一个简单的打包工具,可以用于构建exe、pkg、dmg、deb、rpm格式的安装文件;非模块化的app的构建示例如下

jpackage --name myapp --input lib --main-jar main.jar

345:NUMA-Aware Memory Allocation for G1

实现了NUMA-aware的内存分配,以提升G1在大型机器上的性能

349:JFR Event Streaming

JDK11引入了JFR,使用的时候先dump到磁盘上然后再分析;而在JDK14则支持stream方式来进行持续性的监控,示例如下

public class AgentMain implements Runnable {

    public static void premain(String agentArgs, Instrumentation inst) {
        try {
            Logger.getLogger("AgentMain").log(
                    Level.INFO, "Attaching JFR Monitor");
            new Thread(new AgentMain()).start();
        } catch (Throwable t) {
            Logger.getLogger("AgentMain").log(
                    Level.SEVERE,"Unable to attach JFR Monitor", t);
        }
    }

    @Override
    public void run() {
        var sender = new JfrStreamEventSender();
        try (var rs = new RecordingStream()) {
            rs.enable("jdk.CPULoad")
                    .withPeriod(Duration.ofSeconds(1));
            rs.enable("jdk.JavaMonitorEnter")
                    .withThreshold(Duration.ofMillis(10));
            rs.onEvent("jdk.CPULoad", sender);
            rs.onEvent("jdk.JavaMonitorEnter", sender);
            rs.start();
        }
    }
}

352:Non-Volatile Mapped Byte Buffers

该特性新增了java.base/jdk/internal/misc/ExtendedMapMode.java以支持MappedByteBuffer访问non-volatile memory (NVM)

358:Helpful NullPointerExceptions

该特性可以更好地提示哪个地方出现的空指针,需要通过-XX:+ShowCodeDetailsInExceptionMessages开启,示例如下

public class NullPointerExample {

    public record City(String name){

    }

    public record Location(City city) {

    }

    public record User(String name, Location location) {

    }

    public static void main(String[] args){
        User user = new User("hello", new Location(null));
        System.out.println(user.location().city().name());
    }
}

输出如下

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.example.NullPointerExample$City.name()" because the return value of "com.example.NullPointerExample$Location.city()" is null
    at com.example.NullPointerExample.main(NullPointerExample.java:25)

359:Records (Preview)

JDK14引入了preview版本的record类型,示例如下

public record Point(int x, int y) {

    public Point {
        System.out.println(String.format("(%d,%d)", x, y));
    }

    public Point(int value) {
        this(value, value);
    }

    public static Point of(int value) {
        return new Point(value, value);
    }
}

javap反编译如下

javac --enable-preview -source 14 Point.java
javap -verbose Point.class
Compiled from "Point.java"
public final class com.example.domain.Point extends java.lang.Record {
  public com.example.domain.Point(int, int);
  public static com.example.domain.Point of(int);
  public java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int x();
  public int y();
}

可以看见Point继承了java.lang.Record,而且通过invokedynamic提供了final的hashCode及equals

361:Switch Expressions (Standard)

JDK12引入的switch在JDK14变为正式版本,正式版主要是用->来替代以前的:+break;另外就是提供了yield来在block中返回值,示例如下

    public void testSwitchWithArrowBlockAndYield() {
        int n = 3;
        String quantityString = switch (n) {
            case 1 -> "one";
            case 2 -> "two";
            default -> {
                System.out.println("default");
                yield "many";
            }
        };
        System.out.println(quantityString);
    }

362:Deprecate the Solaris and SPARC Ports

废弃了 Solaris/SPARC, Solaris/x64, and Linux/SPARC ports,以在未来的版本中移除

363:Remove the Concurrent Mark Sweep (CMS) Garbage Collector

移除了CMS垃圾收集器,如果在JDK14中使用-XX:+UseConcMarkSweepGC的话,会出现warning,但是不会exit而是以默认的垃圾收集器运行,如下

OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0

364:ZGC on macOS

之前的ZGC只能在linux上使用,现在mac上也能使用ZGC了,示例如下

-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

365:ZGC on Windows

之前的ZGC只能在linux上使用,现在windows(不能低于1803版本)上也能使用ZGC了,示例如下

-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

366:Deprecate the ParallelScavenge + SerialOld GC Combination

废弃了parallel young generation GC与SerialOld GC的组合(-XX:+UseParallelGC与-XX:-UseParallelOldGC配合开启),现在使用-XX:+UseParallelGC -XX:-UseParallelOldGC或者-XX:-UseParallelOldGC都会出现告警如下

OpenJDK 64-Bit Server VM warning: Option UseParallelOldGC was deprecated in version 14.0 and will likely be removed in a future release.

单独使用-XX:+UseParallelGC则开启parallel young and old generation GC algorithms

367:Remove the Pack200 Tools and API

移除了Pack200 API

368:Text Blocks (Second Preview)

JDK13引入的text blocks进行第二轮preview,JDK14的版本主要增加了两个escape sequences,分别是\<line-terminator>\s escape sequence,示例如下

    @Test
    public void testTextBlockWithTwoNewEscapeSequences() {
        String inOneLine = """
                Lorem ipsum dolor sit amet, consectetur adipiscing \
                elit, sed do eiusmod tempor incididunt ut labore \
                et dolore magna aliqua.\
                """;
        System.out.println(inOneLine);

        String singleSpace = """
                red  \s
                green\s
                blue \s
                """;
        System.out.println(singleSpace);
    }

370:Foreign-Memory Access API (Incubator)

提供了incubator版本的API用于操纵堆外内存,使用示例如下

    @Test
    public void testForeignMemoryAccessAPI() {
        SequenceLayout intArrayLayout
                = MemoryLayout.ofSequence(25,
                MemoryLayout.ofValueBits(32,
                        ByteOrder.nativeOrder()));

        VarHandle intElemHandle
                = intArrayLayout.varHandle(int.class,
                MemoryLayout.PathElement.sequenceElement());

        try (MemorySegment segment = MemorySegment.allocateNative(intArrayLayout)) {
            MemoryAddress base = segment.baseAddress();
            for (int i = 0; i < intArrayLayout.elementCount().getAsLong(); i++) {
                intElemHandle.set(base, (long) i, i);
            }
        }
    }

细项解读

上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见JDK 14 Release Notes,这里举几个例子。

添加项

  • New Method to SAX ContentHandler for Handling XML Declaration (JDK-8230814)

给SAX ContentHandler新增了方法,如下

    default void declaration(String version, String encoding, String standalone)
        throws SAXException
    {
        //no op
    }

移除项

  • Removal of sun.nio.cs.map System Property (JDK-8229960)

移除了sun.nio.cs.map属性

  • Removed Deprecated java.security.acl APIs (JDK-8191138)

移除了java.security.acl

  • Removal of the Default keytool -keyalg Value (JDK-8214024)

移除了默认的keytool -keyalg

废弃项

  • Thread Suspend/Resume Are Deprecated for Removal (JDK-8231602)

废弃了Thread的如下方法

Thread.suspend()
Thread.resume()
ThreadGroup.suspend()
ThreadGroup.resume()
ThreadGroup.allowThreadSuspension(boolean)

已知问题

  • Text Visibility Issues in macOS Dark Mode (JDK-8228555)

已知在macOS上的Dark Mode有Text Visibility Issues

其他事项

  • Thread.countStackFrames Changed to Unconditionally Throw UnsupportedOperationException (JDK-8205132)

Thread.countStackFrames开启转为无条件地抛出UnsupportedOperationException

小结

Java14主要有如下几个特性

doc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容