Java 13权威指南 - CodeFX


Java 13在一小时前发布,这里有你需要了解的一切:
如果您想自己使用代码,请查看GitHub上的Java X Demo
以下是Java 13最常见的IDE和构建工具的最低版本要求:

  • IntelliJ IDEA:2019.2
  • Eclipse:2019-09(4.13),带有Java 13支持插件
  • Maven:3.5.0
    • 编译器插件:3.8.0
    • surefire和failsafe:2.22.0
    • 使用ASM的插件(例如,阴影插件)也可能需要更新
  • Gradle:6.0

在编译为Java 13字节码时,请记住,您可能必须更新依赖于字节码操作的所有依赖项,例如Spring,Hibernate,Mockito等。

如果要使用文本块或 Switch表达式(有关它们的详细信息,请参见下文),请在构建工具配置中包含此内容:

<!-- Maven's pom.xml -->
<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <release>13</release>
        <compilerArgs>
            --enable-preview
        </compilerArgs>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>--enable-preview</argLine>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <configuration>
        <argLine>--enable-preview</argLine>
    </configuration>
</plugin>

// Gradle's build.gradle
compileJava {
    options.compilerArgs += [
"--enable-preview"]
}
test {
    jvmArgs '--enable-preview'
}

在IntelliJ IDEA中,将模块的语言级别设置为13(预览)。在Eclipse中,找到Java Compiler配置并选中Enable preview features。

升级到Java 13时获得的新语法:

文本块
将跨越多行的字符串放入代码中一直是Java的难点。现在,20多年后,我们终于得到了易于使用的多行字符串,称为文本块:

// ugh! 以前写法
String jsonLiteral =
""
    +
"{\n"
    +
"\tgreeting: \"Hello\",\n"
    +
"\taudience: \"World\",\n"
    +
"\tpunctuation: \"!\"\n"
    +
"}\n";
// yay! java13写法
String jsonBlock =
"""
    {
        greeting:
"Hello",
        audience:
"World",
        punctuation:
"!"
    }
   
""";


从Switch表达式返回值
在Java 12和13中引入了Switch表达式。在12中,您将使用break定义返回值 :


boolean result = switch (Bool.random()) {
    case TRUE -> {
        System.out.println("Bool true");
        break true;
    }
    case FALSE -> {
        System.out.println(
"Bool false");
        break false;
    }
    case FILE_NOT_FOUND -> {
        throw new UncheckedIOException(
           
"This is ridiculous!",
            new FileNotFoundException());
    }


Java 13中你需要使用 yield:

boolean result = switch (Bool.random()) {
    case TRUE -> {
        System.out.println("Bool true");
       
// `yield` instead of `break`
        yield true;
    }
    case FALSE -> {
        System.out.println(
"Bool false");
        yield false;
    }
    case FILE_NOT_FOUND -> {
        throw new UncheckedIOException(
           
"This is ridiculous!",
            new FileNotFoundException());
    }

新的字符串方法
String有三种新方法:

  • String :: stripIndent的行为与编译器用于删除文本块缩进的算法相同。
  • 类似地, String :: translateEscapes在转换字符串中的转义序列时公开编译器的行为。
  • String :: formatted是重新实现静态方法 String :: format的实例方法 。这意味着要调用 “价值:%s” 。formatted (value )等效于 String 。format (“Value:%s” ,value ) ,但更方便一点。

NIO改进
在NIO API中有一些小的改进:

⇝JDK -5029431:添加绝对批量 放置和 获取方法
⇝JDK -8218418: 文件。createSymbolicLink应该使用 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
⇝ JDK-8215467: 文件。是否隐藏应返回 真正的 Windows上的隐藏目录
⇝ JDK-8218875:添加 文件系统。newFileSystem (Path ,Map < String ,?> ) 方法

Socket和ServerSocket重新实现
Project Loom将引入光纤fibers (由JVM管理的轻量级线程),其中一部分是使块的所有代码采用相同的路径(因为这些路径随后被更改为不再阻塞线程)。
Java中重要堵塞是在 java.net.Socket 和java.net.ServerSocket下的类,它们的实现非常陈旧,并没有与Loom的方法一致,因此在准备将来的更改时,此API已重新实现。这对我们来说不应该引起注意。

为AppCDS创建类数据存档
应用程序类 - 数据共享(AppCDS)在Java 10中免费提供,并在12和13中得到改进。它通过将大部分类加载工作移出来减少启动时间(减少10%到几乎50%)和响应时间异常值程序运行。AppCDS不是在需要时从JAR加载类数据,而是准备一个不可变的归档文件,并在JVM启动时将其映射到内存中。(或“JVM”,因为存档可以在多个实例之间共享。)
在Java 10上,使用存档过去是一个三步过程:

  • 创建要归档的类列表
  • 创建档案
  • 与存档一起发布

Java 12通过引入JVM附带并自动使用的JDK类的默认存档来放宽这一点。但您仍然必须完成上述步骤才能创建包含应用程序类的存档。这就是Java 13发挥作用的地方。
新的选项 - XX:ArchiveClassesAtExit告诉JVM照常运行,但退出(如果它没有崩溃),对类数据写入到指定的文件。然后可以将其用于未来的计划发布:


# run without CDS & create archive
java
    -XX:ArchiveClassesAtExit=dyn-cds.jsa
    -jar target/java-x.jar
 
# use created archive
java
    -XX:SharedArchiveFile=dyn-cds.jsa
    -jar target/java-x.jar


此方法使用所谓的动态CDS存档,使该功能更易于使用。如果您关心反射启动时间,请试一试!

ZGC使用内存
Oracle的Z垃圾收集器(ZGC)是一种可扩展的低延迟垃圾收集器,旨在满足独立于堆或实时集大小(从几百MB到几TB)的暂停时间,并保持在10 ms以下。在Java 13中,堆大小可以是16 TB,ZGC可以将未使用的内存返回给操作系统。命令行参数 - XX:ZUncommitDelay = <秒>可以用于配置当发生这种情况。
然后有一个新的命令行标志 - XX:SoftMaxHeapSize,通知垃圾收集器,试图限制堆到指定的大小。如果本来耗尽内存,它允许使用更多的内存,-Xmx就应该可以很好地用于返回未使用的内存。