Java 14的新增功能

Java 14徽标

Java 14已于2020年3月17日正式发布,请在此处下载Java 14

Java 14功能。

JEP 305:用于instanceof的模式匹配(预览)

在Java 14之前,我们使用instanceof-and-cast来检查对象的类型并将其转换为变量。

if (obj instanceof String) {        // instanceof
    String s = (String) obj;          // cast
    if("jdk14".equalsIgnoreCase(s)){
        //...
    }
  }else {
	   System.out.println("not a string");
  }

现在,在Java 14中,我们可以像上面那样重构上面的代码:

if (obj instanceof String s) {      // instanceof, cast and bind variable in one line.
      if("jdk4".equalsIgnoreCase(s)){
          //...
      }
  }else {
	   System.out.println("not a string");
  }

如果objString的实例,则将其强制转换为String并分配给绑定变量s

JEP 343:包装工具(培养箱)

新的jpackage工具,用于将Java应用程序打包到特定于平台的程序包中。

  • Linux:deb和rpm
  • macOS:pkg和dmg
  • Windows:MSI和EXE

例如,将JAR文件打包到Windows上的exe文件中。

PS Update jpackage示例在这里

JEP 345:针对G1的NUMA感知内存分配

新的NUMA感知内存分配模式提高了大型计算机上的G1性能。 添加+XX:+UseNUMA选项将其启用。

JEP 349:JFR事件流

改进了现有的JFR以支持事件流,这意味着现在我们可以实时传输JFR事件,而无需将记录的事件转储到磁盘并手动解析它。

JDK Flight Recorder(JFR)是用于收集有关正在运行的Java应用程序的诊断和性能分析数据的工具。 通常,我们开始记录,停止记录,将记录的事件转储到磁盘以进行分析,它可以很好地进行概要分析,分析或调试。

相关的 JEP 328:飞行记录器

PS Update JFR事件流示例在此处 _

JEP 352:非易失性映射字节缓冲区

改进的FileChannel API可以创建MappedByteBuffer来访问非易失性内存(NVM) ,该内存即使在关闭电源后也可以检索存储的数据。 例如,此功能可确保将可能仍在高速缓存中的所有更改写回到内存中。

PS仅Linux / x64和Linux / AArch64 OS支持此功能!

JEP 358:有用的NullPointerExceptions

通过告诉哪个变量为空,改进了对NullPointerExceptions的描述。 添加-XX:+ShowCodeDetailsInExceptionMessages选项以启用此功能。

抛出NullPointerException简单Java文件。

Test.java
import java.util.Locale;

public class Test {

    public static void main(String[] args) {

        String input = null;
        String result = showUpperCase(input); // NullPointerException
        System.out.println(result);

    }

    public static String showUpperCase(String str){
        return str.toUpperCase(Locale.US);
    }

}

在Java 14.之前

$ /usr/lib/jvm/jdk-14/bin/java Test

Exception in thread "main" java.lang.NullPointerException
	at Test.showUpperCase(Test.java:15)
	at Test.main(Test.java:9)

具有-XX:+ShowCodeDetailsInExceptionMessages选项的Java 14。

$ /usr/lib/jvm/jdk-14/bin/java -XX:+ShowCodeDetailsInExceptionMessages Test

Exception in thread "main" java.lang.NullPointerException:
  Cannot invoke "String.toUpperCase(java.util.Locale)" because "<parameter1>" is null
	at Test.showUpperCase(Test.java:15)
	at Test.main(Test.java:9)

PS请默认启用此功能🙂

JEP 359:记录(预览)

一个称为record的新类(又称为数据类),它是一个最终类,而不是抽象类,并且它的所有字段也是最终的。 record将在编译期间自动生成繁琐的constructors public getequals()hashCode()toString()

PS没有设置员,所有字段都是最终的。

一个record或数据类,创建类名称和变量,我们就可以开始使用它了。

Point.java
record Point(int x, int y) { }
Test.java
public class Test {

    public static void main(String[] args) {

        Point p1 = new Point(10, 20);      
        System.out.println(p1.x());         // 10
        System.out.println(p1.y());         // 20

        Point p2 = new Point(11, 22);
        System.out.println(p2.x());         // 11
        System.out.println(p2.y());         // 22

	      Point p3 = new Point(10, 20);     
        System.out.println(p3.x());         // 10
        System.out.println(p3.y());         // 20

        System.out.println(p1.hashCode());  // 330
        System.out.println(p2.hashCode());  // 363
        System.out.println(p3.hashCode());  // 330

        System.out.println(p1.equals(p2));  // false
        System.out.println(p1.equals(p3));  // true
        System.out.println(p1.equals(p3));  // true

    }

}

使用--enable-preview对其进行测试。

$ /usr/lib/jvm/jdk-14/bin/javac --enable-preview --release 14 Point.java
$ /usr/lib/jvm/jdk-14/bin/javac --enable-preview --release 14 Test.java

$ /usr/lib/jvm/jdk-14/bin/java --enable-preview Test

输出量

10
20
11
22
10
20
330
363
330
false
true
true

进一步阅读
有关更多record示例,请参考此Java 14 Record数据类。

PS更新记录或数据类示例在这里

JEP 361:开关表达式(标准)

开关表达式是Java 12和Java 13中的预览功能。 现在它已正式成为JDK标准功能,这意味着从Java 14开始,我们可以通过开关表达式返回值,而无需指定--enable-preview选项。

回顾一下; 我们可以使用yieldswitch返回一个值。

private static int getValueViaYield(String mode) {
        int result = switch (mode) {
            case "a", "b":
                yield 1;
            case "c":
                yield 2;
            case "d", "e", "f":
								// do something here...
							 	System.out.println("Supports multi line block!");
                yield 3;
            default:
                yield -1;
        };
        return result;
    }

或通过标签规则或箭头。

private static int getValueViaArrow(String mode) {
        int result = switch (mode) {
            case "a", "b" -> 1;
            case "c" -> 2;
            case "d", "e", "f" -> {
                // do something here...
                System.out.println("Supports multi line block!");
                yield 3;
            }
            default -> -1;
        };
        return result;
    }

请参阅此Java 13 Switch Expression中的示例。

JEP 362:弃用Solaris和SPARC端口

放弃对Solaris / SPARC,Solaris / x64和Linux / SPARC端口的支持,更少的平台支持意味着更快地交付新功能。

JEP 363:删除并发标记扫描(CMS)垃圾收集器

Java 9 – JEP 291已弃用此并发标记扫描(CMS)垃圾收集器,现在正式将其删除。

/usr/lib/jvm/jdk-14/bin/java -XX:+UseConcMarkSweepGC Test

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

JEP 364:macOS上的ZGC(实验性)

Java 11 – JEP 333在Linux上引入了Z垃圾收集器(ZGC),现在可移植到macOS。

Windows上的JEP 365:ZGC(实验性)

Java 11 – JEP 333在Linux上引入了Z垃圾收集器(ZGC),现在可移植到Windows版本== 1803。

JEP 366:弃用ParallelScavenge + SerialOld GC组合

由于较少的使用和较高的维护工作量,Java 14不赞成使用并行年轻代和串行老一代GC算法的组合。

/usr/lib/jvm/jdk-14/bin/java -XX:-UseParallelOldGC Test

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

JEP 367:删除Pack200工具和API

Java 11 – JEP 336不推荐使用pack200unpack200工具以及java.util.jar软件包中的Pack200 API,现在正式将其删除。

JEP 368:文本块(第二预览)

第一个预览版出现在Java 13 – JEP 354中 ,现在又添加了两个新的转义序列:

  • \<end-of-line>禁止行终止。
  • \s被翻译成一个空格。
Test.java
public class Test {

    public static void main(String[] args) {

        String html = "<html>\n" +
                      "   <body>\n" +
                      "      <p>Hello, World</p>\n" +
                      "   </body>\n" +
                      "</html>\n";

        String java13 = """
                        <html>
                            <body>
                                <p>Hello, World</p>
                            </body>
                        </html>
                        """;

        String java14 = """
                        <html>
                            <body>\
                                <p>Hello, '\s' World</p>\
                            </body>
                        </html>
                        """;

        System.out.println(html);
        System.out.println(java13);
        System.out.println(java14);

    }

}
$ /usr/lib/jvm/jdk-14/bin/javac --enable-preview --release 14 Test.java
$ /usr/lib/jvm/jdk-14/bin/java --enable-preview Test

输出量

html>
   <body>
      <p>Hello, World</p>
   </body>
</html>

<html>
    <body>
        <p>Hello, World</p>
    </body>
</html>

<html>
    <body>        <p>Hello, ' ' World</p>    </body>
</html>

进一步阅读
有关更多Java文本块示例的信息,请参考此Java多行字符串,文本块

JEP 370:外部存储器访问API(孵化器)

孵化器模块,允许Java API访问Java堆外部的外部内存。

Test.java
import jdk.incubator.foreign.*;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;

public class Test {

    public static void main(String[] args) {

	     VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());

        try (MemorySegment segment = MemorySegment.allocateNative(1024)) {

            MemoryAddress base = segment.baseAddress();

            System.out.println(base);                 // print memory address

	          intHandle.set(base, 999);                 // set value 999 into the foreign memory

            System.out.println(intHandle.get(base));  // get the value from foreign memory

        }

    }

}

编译并使用孵化器模块jdk.incubator.foreign运行。

$ /usr/lib/jvm/jdk-14/bin/javac --add-modules jdk.incubator.foreign Test.java

warning: using incubating module(s): jdk.incubator.foreign
1 warning

$ /usr/lib/jvm/jdk-14/bin/java --add-modules jdk.incubator.foreign Test

WARNING: Using incubator modules: jdk.incubator.foreign
MemoryAddress{ region: MemorySegment{ id=0x4aac6dca limit: 1024 } offset=0x0 }
999

进一步阅读– jdk.incubator.foreign Javadoc

$ git clone https://github.com/mkyong/core-java

$ cd java-14

参考文献

翻译自: https://mkyong.com/java/what-is-new-in-java-14/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值