Java 11特性

我们还没有完全沉浸在Java 10中,Java 11已经来了。 Java 11的重要性不仅仅是因为几个原因。 Oracle已经重新调整了其支持模型,并提出了一个发布系列,将带来快速更新,大约每6个月一次。 他们已经改变了许可和支持模型,这意味着如果您下载Java 11 Oracle JDK,将需要支付商业使用费用。

那是否意味着我现在需要为Java付费?不一定。除非您下载Oracle JDK并在生产中使用。

注意: IntelliJ IDEA 2018.2.4社区版已经支持Java 11。

1. Java 11为什么重要?

Java 11是继Java 8之后的第二个LTS版本。自Java 11以来,Oracle JDK将不再免费供商业使用。您可以在开发阶段使用它,但要在商业上使用,您需要购买许可证。如果不购买,您可能随时会收到来自Oracle的发票账单! Java 10是最后一个可以免费下载的Oracle JDK。 Oracle于2019年1月停止支持Java 8。您需要支付更多支持费用。您可以继续使用,但将不会获得任何补丁/安全更新。

自Java 11以来,Oracle将不再为任何单个Java版本提供免费的长期支持(LTS)。

尽管 Oracle JDK 不再免费,但你始终可以从 Oracle 或其他提供商(如 AdoptOpenJDK、Azul、IBM、Red Hat 等)下载 Open JDK 构建版本。在我看来,除非你要寻求企业级的使用,并愿意支付支持费用,否则你可以使用 OpenJDK 并在必要时进行升级。

2. 我应该下载哪个 JDK 构建版本?它们各自的优点是什么?由于 Oracle 已经创建了一个发布列车,每六个月就会推出一个新版本,如果你正在使用 Oracle 提供的免费 Open JDK,那么你需要每六个月更新一次,因为一旦新版本发布,Oracle 将不再提供免费更新。这对公司来说可能是具有挑战性的。向 Oracle 支付商业支持费用,并仅从一个 LTS 版本迁移到下一个 LTS 版本。这样,你将获得对 Java 11 直到 2026 年的所有更新和支持。你可以在 2022 年下载 Java 17。即使支持结束后,仍然保持免费的 Java 版本。尽管你将不会获得安全更新,但它可能会打开安全漏洞。Oracle 不会为 Java 9 和 Java 10 提供商业支持或更新。你需要寻找其他替代版本以保持免费使用。

了解了Java 11附带的功能,现在让我们分析Java 11对开发人员的重要特性。我们还将讨论一些重要的JEPs。注意:JavaFX将作为一个独立的模块提供,不再与Java JDK的6个月发布周期绑定。

3. 如何下载Java 11免费版本?

您可以从这个链接下载生产就绪的OpenJDK版本。二进制文件以tar或zip格式提供,只需解压缩它们并设置环境变量以使用java编译器和java命令。

4. Java 11特性

一些重要的Java 11特性包括:

  • 使用单个命令运行Java文件
  • String类中的新实用方法
  • lambda参数的局部变量语法
  • 基于嵌套的访问控制
  • JEP 321:HTTP客户端
  • 从文件中读取/写入字符串
  • JEP 328:飞行记录器

让我们讨论从JEP过程中引入的Java 11的新功能。

4.1) 用单个命令运行Java文件

一个主要的变化是你不需要首先使用 javac 工具编译Java源文件。你可以直接用 java 命令运行文件,它会隐式地进行编译。这个特性属于JEP 330。以下是Java 11中引入的 Java字符串 类的新方法的一瞥:

4.2) Java字符串方法

isBlank() – 这个实例方法返回一个布尔值。空字符串和只包含空白字符的字符串被视为空白。

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // 你的代码在这里!
        
        System.out.println(" ".isBlank()); //true
        
        String s = "Anupam";
        System.out.println(s.isBlank()); //false
        String s1 = "";
        System.out.println(s1.isBlank()); //true
    }
}

lines() 这个方法返回一个字符串流,它是由所有以行分割的子字符串组成的集合。

import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws Exception {
        
        String str = "JD\nJD\nJD"; 
        System.out.println(str);
        System.out.println(str.lines().collect(Collectors.toList()));
    }
}

上述代码的输出是: strip(), stripLeading(), stripTrailing() strip() – 移除字符串的开头和结尾的空格。

但我们已经有 trim() 了。那么 strip() 有什么必要呢? strip() 是对 trim() 的“Unicode-aware”演化。当 trim() 被引入时,Unicode 还未演化。现在,新的 strip() 移除所有类型的前导和尾随空白(使用方法 Character.isWhitespace(c) 来判断一个 Unicode 是否为空白)

下面是使用上述三种方法的示例:

public class Main {
    public static void main(String[] args) throws Exception {
        // 你的代码在这里!
        
        String str = " JD "; 
        System.out.print("Start");
        System.out.print(str.strip());
        System.out.println("End");
        
        System.out.print("Start");
        System.out.print(str.stripLeading());
        System.out.println("End");
        
        System.out.print("Start");
        System.out.print(str.stripTrailing());
        System.out.println("End");
    }
}

以上代码在控制台的输出是: repeat(int) repeat 方法简单地将字符串重复指定次数,以 int 形式给出。

public class Main {
    public static void main(String[] args) throws Exception {
        // 你的代码在这里!
        
        String str = "=".repeat(2);
        System.out.println(str); //prints ==
    }
}

4.3) 用于 Lambda 参数的局部变量语法

JEP 323,Java 11 中唯一的语言功能更新是对 Lambda 参数的局部变量语法。在 Java 10 中,引入了局部变量类型推断。因此,我们可以从右侧推断变量的类型 – var list = new ArrayList<String>(); JEP 323 允许在隐式类型的 Lambda 表达式中使用 var 来声明形式参数。现在我们可以定义:

(var s1, var s2) -> s1 + s2

这在 Java 8 中也是可能的,但在 Java 10 中被移除了。现在在 Java 11 中又回来了,以保持一致性。但为什么需要这个呢,当我们可以在 Lambda 中省略类型呢? 如果你需要应用一个注解,比如 @Nullable,你不能在没有定义类型的情况下这样做。此功能的限制 – 必须在所有参数上指定类型 var,或者不指定。像下面这样的事情是不可能的:

(var s1, s2) -> s1 + s2 //no skipping allowed
(var s1, String y) -> s1 + y //no mixing allowed

var s1 -> s1 //not allowed. Need parentheses if you use var in lambda.

4.4) 基于嵌套的访问控制

在 Java 11 之前,这是可能的:

public class Main {
 
    public void myPublic() {
    }
 
    private void myPrivate() {
    }
 
    class Nested {
 
        public void nestedPublic() {
            myPrivate();
        }
    }
}

主类的私有方法可以从上述嵌套类中以上述方式访问。但如果我们使用 Java 反射,它会抛出一个 IllegalStateException

Method method = ob.getClass().getDeclaredMethod("myPrivate");
method.invoke(ob);

Java 11 嵌套访问控制解决了反射中的这一问题。 java.lang.Class 引入了反射 API 中的三个方法:getNestHost()getNestMembers()isNestmateOf()

4.5) JEP 309: 动态类文件常量

Java 类文件格式现在扩展了对新常量池形式 CONSTANT_Dynamic 的支持。这个 JEP 的目标是通过创建一个可以用用户提供的行为参数化的新常量池形式,来减少开发新形式的可材料化类文件约束的成本和干扰。这提高了性能。

4.6) JEP 318: Epsilon: 一个无操作垃圾收集器

与负责分配内存和释放内存的 JVM 垃圾收集器不同,Epsilon 只分配内存。它为以下事项分配内存:

  • 性能测试。
  • 内存压力测试。
  • VM 接口测试。
  • 极短寿命的作业。
  • 最后一滴延迟改进。
  • 最后一滴吞吐量改进。

现在Elipson只适用于测试环境。在生产环境中会导致OutOfMemoryError并使应用程序崩溃。Elipson的好处是没有内存清理开销。因此,它将提供准确的性能测试结果,我们将无法再进行GC来停止它。注意:这是一个实验性功能。

4.7) JEP 320:移除Java EE和CORBA模块

这些模块在Java 9中已经被弃用。现在它们已完全移除。以下包已移除:java.xml.wsjava.xml.bindjava.activationjava.xml.ws.annotationjava.corbajava.transactionjava.se.eejdk.xml.wsjdk.xml.bind

4.8) JEP 328:飞行记录器

飞行记录器以前曾是Oracle JDK中的商业附加组件,现在已经开源,因为Oracle JDK本身不再免费。 JFR是一种用于从正在运行的Java应用程序中收集诊断和分析数据的分析工具。它的性能开销微不足道,通常低于1%。因此,它可以在生产应用程序中使用。

4.9) JEP 321: HTTP Client

Java 11标准化了Http Client API。新的API支持HTTP/1.1和HTTP/2。它旨在改善客户端发送请求和从服务器接收响应的整体性能。它还原生支持WebSockets。

4.10) 读写字符串到文件

Java 11致力于使读写字符串变得更加方便。它引入了以下方法来读取和写入文件:

  • readString()
  • writeString()

以下代码展示了一个示例

Path path = Files.writeString(Files.createTempFile("test", ".txt"), "This was posted on JD");
System.out.println(path);
String s = Files.readString(path);
System.out.println(s); //This was posted on JD

4.11) JEP 329: ChaCha20 和 Poly1305 加密算法

Java 11 提供了 ChaCha20 和 ChaCha20-Poly1305 密码算法的实现。这些算法将会在 SunJCE 提供者中实现。

4.12) JEP 315: 改进 Aarch64 Intrinsics

改进现有的字符串和数组内置函数,并在 AArch64 处理器上为 java.lang.Math 的 sin、cos 和 log 函数实现新的内置函数。

4.13) JEP 333: ZGC: 一种可扩展的低延迟垃圾收集器(实验性)

Java 11 引入了低延迟 GC。这是一个实验性功能。很高兴看到 Oracle 重视 GC。

4.14) JEP 335: 废弃 Nashorn JavaScript 引擎

Nashorn JavaScript 脚本引擎和 API 已被废弃,表明它们将在随后的发布版本中移除。

5. 结论

我们已经介绍了 Java 11 中提供的重要功能和更新。期待 Java 12 发布时再见。

Source:
https://www.digitalocean.com/community/tutorials/java-11-features