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 对开发人员的重要功能。我们还将讨论一些重要的 JEP。注意: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 String类的新方法的预览:
4.2)Java 字符串方法
isBlank() - 此实例方法返回一个布尔值。空字符串和仅包含空格的字符串将被视为空白。
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
// Your code here!
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()
这是“Unicode 感知”的演进trim()
。trim()
引入时,Unicode 并没有演进。现在,新的 strip() 会删除所有类型的前导和尾随空格(检查该方法Character.isWhitespace(c)
以了解 unicode 是否为空格)
下面给出了使用上述三种方法的示例:
public class Main {
public static void main(String[] args) throws Exception {
// Your code here!
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 {
// Your code here!
String str = "=".repeat(2);
System.out.println(str); //prints ==
}
}
4.3)Lambda 参数的局部变量语法
JEP 323 , Lambda参数的局部变量语法是 Java 11 中唯一发布的语言功能。在 Java 10 中,引入了局部变量类型推断。因此,我们可以从 RHS 推断出变量的类型 - var list = new ArrayList<String>();
JEP 323 允许var
使用它来声明隐式类型 lambda 表达式的形式参数。我们现在可以定义:
(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 GC 不同,Epsilon 仅分配内存。它为以下事项分配内存:
- 性能测试。
- 内存压力测试。
- VM接口测试。
- 极其短暂的工作。
- 最后一滴延迟的改进。
- 最后一滴吞吐量的改进。
现在 Elipson 仅适用于测试环境。它将导致生产环境中的OutOfMemoryError并使应用程序崩溃。Elipson 的好处是没有内存清除开销。因此它将提供准确的性能测试结果,我们不再需要 GC 来阻止它。注意:这是一个实验性功能。
4.7)JEP 320:删除 Java EE 和 CORBA 模块
这些模块在Java 9 中已弃用。它们现在已被完全删除。以下软件包已被删除:java.xml.ws
、、、、、、、、、java.xml.bind
java.activation
java.xml.ws.annotation
java.corba
java.transaction
java.se.ee
jdk.xml.ws
jdk.xml.bind
4.8)JEP 328:飞行记录器
Flight Recorder 以前是 Oracle JDK 中的商业附加组件,现在已开源,因为 Oracle JDK 本身不再免费。JFR 是一种分析工具,用于从正在运行的 Java 应用程序中收集诊断和分析数据。它的性能开销可以忽略不计,通常低于 1%。因此,它可以用于生产应用程序。
4.9)JEP 321:HTTP 客户端
Java 11 标准化了 Http CLient API。新 API 同时支持 HTTP/1.1 和 HTTP/2。它旨在提高客户端发送请求和从服务器接收响应的整体性能。它还原生支持 WebSockets。
4.10)从文件读取/写入字符串
Java 11 致力于使 String 的读写更加方便。它引入了以下用于读取和写入文件的方法:
- 读取字符串()
- 写入字符串()
下面的代码展示了一个例子
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 内部函数
改进现有的字符串和数组内在函数,并在 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 发布时我们很快就会见面。