Java 11,作为一个长期支持版本(LTS),在2018年9月发布。它引入了许多新特性和,为开发者提供了更多的工具和选项。在本文中,我们将探讨 11的主要新特性,以及何在实际项目中应用这些特性。以下是Java 11中值得关注的新特性和新功能:
HTTP 客户端 API:Java 11引入了一组标准的HTTP客户端API,可以方便地创建和发送HTTP请求,并支持异步和流式处理。使用这个API可以替换HttpURLConnection和Apache HttpClient等传统的HTTP客户端工具。
var 关键字:var 是Java 10中引入的关键字,Java 11又扩展了它的使用范围。现在可以在Lambda表达式的参数列表中使用 var 来声明变量类型,并且可以在for循环中使用 var 来遍历数组或集合。
集合 API 增强:Java 11中的集合API有一些新增的方法和功能,例如 List.of()、Set.of() 和 Map.of() 可以快速创建不可变的集合。另外,新增了 Collection.toArray(IntFunction
ZGC 垃圾回收器:Java 11中引入了全新的ZGC垃圾回收器,它是一个低停顿的、可扩展的、并行的垃圾回收器,可以处理TB级别的堆内存。相比其他垃圾回收器,ZGC 能够更好地平衡吞吐量、延迟和内存占用。
Epsilon 垃圾回收器:Epsilon 是Java 11中引入的一种新的垃圾回收器,它不执行实际的垃圾回收操作,仅仅负责对内存进行分配和释放。因此,Epsilon 可以用于那些内存使用频繁,但是不需要垃圾回收的场景。
Unicode 10 支持:Java 11支持Unicode 10字符集,可以支持更多的字符和符号,包括 Emoji 和各种符号等。
新版Javadoc:Java 11中改进了Javadoc工具,使其更加易读和易用。新版Javadoc增强了搜索和导航功能,并且支持HTML5和CSS3等最新的Web技术。
Flight Recorder API:Java 11中引入了Flight Recorder API,可以在运行时收集应用程序的性能数据和事件,并将其输出到文件。这个API基于Java Mission Control(JMC),可以帮助开发人员分析和调试Java应用程序。
嵌套访问控制:Java 11中引入了嵌套访问控制,可以让内部类和外部类之间共享私有成员。如果一个类是另一个类的嵌套类,并且它们在同一个源代码文件中,那么它们之间可以互相访问私有成员。
废弃的API:Java 11中废弃了一些API,主要是Java EE 和 CORBA 相关的API,包括 java.corba、java.transaction、javax.enterprise 和 javax.jms 等。
这些仅是Java 11中的一部分新特性和功能,还有很多其他的更新,如新增的加密算法、新增的安全和性能增强等。
Java 11通过JEP 181引入了嵌套类之间更简洁的访问控制。这个特性通过引入新的字节码指令,使得嵌套类之间的访问更加高效。这意味着在Java 11中,嵌套类可以直接访问彼此的私有成员,而无需使用桥接方法。
使用方法:
public class OuterClass {
private int outerValue;
public class InnerClass {
private int innerValue;
public int accessOuterValue() {
return outerValue; // 直接访问外部类的私有成员
}
}
public int accessInnerValue(InnerClass inner) {
return inner.innerValue; // 直接访问内部类的私有成员
}
}
注意事项:
Java 11通过JEP 309为常量池带来了一种新形式:动态常量。动常量允许在运行时析常量值,这使得类文件可以表示更丰富的常量表达式,同时保持紧凑和高效。
使用方法:
动态常量主要用于底层字节码操作和库开发。以下是一个使用invokedynamic
指令创建动态量的示例:
import java.lang.invoke.*;
public class DynamicConstants {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(String.class, int.class);
CallSite cs = (CallSite) lookup.findStatic(DynamicConstants.class, "bootstrap", mt).invoke(0);
String result = (String) cs.getTarget().invoke(42);
System.out.println(result);
}
public static CallSite bootstrap(MethodHandles.Lookup lookup, int value) {
MethodHandle mh = lookup.findStatic(String.class, "valueOf", MethodType.methodType(String.class, int.class));
return new ConstantCallSite(mh);
}
}
注意事项:
Java 11通过JEP 315改进了在Aarch64体系结构上的性能和稳定性。这个特性主要影响底层JVM实现。对于在Aarch64体系结构上运行Java应程序的开发者来说,这意味着更好的性能和稳定性。
注意事项:
Epsilon是一个实验性的垃圾收集器,它不执行任何内存回收操作。这个特性(JEP318)主要用于性能测试和调试。
使用方法:
要启用Epsilon垃圾收集,请在启动Java应用程序时添加JVM参数:
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
注意事项:
Java 11通过JEP 320移除了Java EE和CORBA相关的模块,以减小JDK的体积和复杂性。如果您的应用依赖于这些模块,您需要寻替代方案,例如使用独立的Java EE库。
注意事项:
Java 11引入了JEP 321,为开发者提供了一个新的HTTP客户端API,用于支持HTTP/1.1HTTP/2和WebSocket通信。这个API是在Java 9中引入的incubator模的基础上改进和标准化的。
方法:
以下是一个使用Java 11 HTTP客户端发送GET请求的示例:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}
注意事项:
Java 11通过JEP 323改进了局部变量类型推断(var),使其可以在lambda表达式的参数中使用。
使用方法:
以下是一个使用var
在lambda表达中推断参数类型的示例:
import java.util.List;
import java.util.stream.Collectors;
public class VarInLambda {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map((var name) -> name.length())
.collect(Collectors.toList());
System.out.println(nameLengths);
}
}
注意事项:
var
可以提高代码的简洁性,但请确保在适当的场景中使用它,以保持代码的可读性。Java 11引入了JEP 330,允许开发者直接运行单个Java源文件,而无需先编译。这使得开发者可以更快速地测试和运行简单的Java程序。
使用方法:
要运单个Java源文件,只需在命令行中输入java HelloWorld.java
,其中HelloWorld.java
您要运行的Java源文件。
注意事项:
Java 11引入了JEP 335,它提供了一种新的工具,用于分析模块之间的依赖关系。这有助于开发者更好地理解和管理模块化Java应用程序的依赖关系。
使用方法:
要使用依赖分析工具,请在命令行中输入jdeps
,后跟您要分析的块或类文件的路径。例如:
jdeps -summary my-module.jar
注意事项:
-jdeps
工具可以帮助更好地理解和管理您的应用程序的依赖关系。在迁移到Java 11之前,您可以使用这个工具检查您的应用程序是否依赖于已移除模块。
Java 11是一个里程碑式的版本,它引入了一些显著的改进和变化,同时也修复了许多已知的Bug。以下是Java 11的修复Bug、移除项、废弃项和未解决问题,以及其他事项的详细描述:
Java 11修复了大量已知的Bug,包括:
当Java 11发布时,Oracle发布了一个官方公告来描述Java 11修复了哪些Bug。下面是Java 11修复的一些主要Bug:
Java虚拟机中最常见的Bug是安全漏洞。Java 11修复了JDK中多个严重的安全漏洞。此外,Java 11还修复了以下Bug:
Java标准库中的Bug也得到了修复,包括:
Java 11还修复了许多与组件和工具相关的Bug,包括:
Java 11中移除了一些不再被支持的标志和API,包括:
Java 11中还废弃了一些API和功能,包括:
在Java 11中仍然存在一些已知的问题,包括:
Java 11引入了许多新特性和功能,使得开发者可以更高效地编写、测试和运行Java用程序。在迁移到Java 11之前,请确保您了解这些新特性,并根据需要更新您的应用程序和依赖库。
如果您想更深入地了解Java 11的新特性和功能,可以查阅Oracle官方文档或其他相关的学习资源。同时,在实际开发中,建议先使用Java 11的新特性进行一些小规模的实验和测试,并逐步应用到实际项目中,以确保应用程序的正确性和稳定性。