- Java 10 教程
- Java 10 - 主页
- Java 10 - 概述
- Java 10 - 环境设置
- Java 10 - 基于时间的发布版本控制
- Java 10 - 局部变量类型推断
- Java 10 - 新 API 和选项
- Java 10 - 删除的功能和选项
- Java 10 - 已弃用的功能和选项
- Java 10 - JIT 编译器
- Java 10 - 类数据共享
- Java 10 - 增强的垃圾收集
- Java 10 - 区域设置增强
- Java 10 - 堆分配
- Java 10 - 统一的 JDK 森林
- Java 10 - 根证书
- Java 10 - 线程本地握手
- Java其他版本教程
- Java教程
- Java 8 教程
- Java 9 教程
- Java 10 有用资源
- Java 10 - 快速指南
- Java 10 - 有用的资源
- Java 10 - 讨论
Java 10 - 快速指南
Java 10 - 概述
Java 10 是 Java 发布节奏中的一个主要版本,于 2018 年 3 月 10 日发布。通过 Java 10,Oracle 将 Java 发布节奏更改为新模型,即 Oracle Java SE 产品的 6 个月发布节奏和 LTS 模型。LTS 模型代表长期支持模型。
从 Java 10 开始,Oracle 每 6 个月发布一个新版本的 Java,每个版本包含一到两个主要功能。Oracle 使用发布序列概念。每个发布系列计划为期 6 个月。在此时间表内开发的功能将在版本中提供,否则功能将移至下一个版本系列。
Oracle JDK 与 OpenJDK
大多数 Oracle JDK 二进制文件都是 Oracle 专有的并获得许可,并且对重新分发有多种限制。而 OpenJDK 对开发者社区更加友好。从 Java 10 开始,Oracle 决定将 OpenJDK 推广为主要 JDK,以促进基于社区的 Java 开发。Oracle 将继续生产自己的 JDK,但会在 3 年后发布,并将其称为 LTS 版本。因此 OpenJDK 二进制文件将每六个月发布一次。
OpenJDK 对云和容器友好,因为它可以作为容器的一部分自由分发。所以Oracle推广OpenJDK的举动让java对于云或者容器的开发部署更加友好。
Java 9 和 Java 10 是非 LTS 版本。Java 11 版本是 LTS 版本。
新功能
以下是 Java 10 中引入的主要新功能。
JEP 286 - 局部变量类型推断
JEP 322 - 基于时间的发布版本控制
JEP 304 - 垃圾收集器接口
JEP 307 - G1 的并行完整 GC
JEP 316 - 替代内存设备上的堆分配
JEP 296 - 将 JDK 森林合并到单个存储库中
JEP 310 - 应用程序类数据共享
JEP 314 - 附加 Unicode 语言标签扩展
JEP 319 - 根证书
JEP 317 - 基于 Java 的实验性 JIT 编译器
JEP 312 - 线程局部握手
JEP 313 - 删除本机标头生成工具
JEP 319 - 根证书
JEP 319 - 根证书
Java 10 通过新方法和选项增强了 70 多个 API,并删除了已弃用的 API 和选项。我们将在接下来的章节中看到这些变化。
Java 10 - 环境设置
在线现场演示选项
我们已经在线设置了Java编程环境,以便您可以在线编译和执行所有可用的示例。它使您对所阅读的内容充满信心,并使您能够使用不同的选项验证程序。请随意修改任何示例并在线执行。
使用以下示例代码框右上角的“实时演示”选项尝试以下示例 -
public class MyFirstJavaProgram { public static void main(String []args) { System.out.println("Hello World"); } }
对于本教程中给出的大多数示例,您将在我们网站右上角的代码部分中找到“实时演示”选项,该选项将带您进入在线编译器。因此,请充分利用它并享受学习的乐趣。
本地环境设置
如果您想设置自己的 Java 编程语言环境,那么本节将指导您完成整个过程。请按照以下步骤设置您的 Java 环境。
Java SE 可供免费下载。要下载,请单击此处,请下载与您的操作系统兼容的版本。
按照说明下载 Java,然后运行.exe以在您的计算机上安装 Java。在计算机上安装 Java 后,您需要设置环境变量以指向正确的安装目录。
设置 Windows 2000/XP 的路径
假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -
右键单击“我的电脑”并选择“属性”。
单击“高级”选项卡下的“环境变量”按钮。
现在,编辑“Path”变量并在其末尾添加 Java 可执行文件目录的路径。例如,如果路径当前设置为C:\Windows\System32,则按以下方式编辑它
C:\Windows\System32;c:\Program Files\java\jdk\bin。
设置Windows 95/98/ME的路径
假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -
-
编辑“C:\autoexec.bat”文件并在末尾添加以下行 -
设置路径=%PATH%;C:\Program Files\java\jdk\bin
设置 Linux、UNIX、Solaris、FreeBSD 的路径
应将环境变量 PATH 设置为指向 Java 二进制文件的安装位置。如果您在执行此操作时遇到问题,请参阅您的 shell 文档。
例如,如果您使用 bash 作为 shell,那么您可以在.bashrc末尾添加以下行-
导出 PATH=/path/to/java:$PATH'
流行的 Java 编辑器
要编写 Java 程序,您需要一个文本编辑器。市场上还有更复杂的 IDE。最流行的简要描述如下 -
记事本- 在 Windows 计算机上,您可以使用任何简单的文本编辑器,例如记事本(本教程推荐)或写字板。Notepad++ 也是一个免费的文本编辑器,增强了功能。
Netbeans - 它是一个开源且免费的 Java IDE,可以从https://www.netbeans.org/index.html下载。
Eclipse - 它也是由 Eclipse 开源社区开发的 Java IDE,可以从https://www.eclipse.org/下载。
IDE或集成开发环境,提供所有常见的工具和设施来帮助编程,例如源代码编辑器、构建工具和调试器等。
Java 10 - 基于时间的发布版本控制
从 Java 10 开始,Oracle 为 Java 版本引入了严格的基于时间的版本控制模型。现在,Java 每六个月就会发布一个主要版本。Java 10 于 2018 年 3 月发布,今后所有主要版本都计划在未来几年的 3 月和 9 月发布。版本进一步分为三大类。
功能版本- 功能版本包含特定于语言的功能、JVM 功能、新的/改进的 API、API 的删除/弃用。这些功能发布的时间是固定的,并且对特定版本中包含的功能没有限制。如果正在开发的功能不是最新版本的一部分,那么它将计划在下一个版本中。
更新版本- 更新版本包括错误修复、安全问题修复、回归修复等。每个更新版本计划于一月、四月、七月和十月每季度发布。在宣布下一个功能版本之前,每个功能版本将收到两个更新版本。
长期支持 (LTS) 版本- 从 2018 年 9 月开始,将每三年发布一次长期支持版本。Oracle 将在未来三年内为此版本提供支持和更新。此版本主要面向在生产部署中使用 Java 的企业。
版本格式
现在的版本遵循以下格式。
$FEATURE.$INTERIM.$UPDATE.$PATCH
在哪里
$FEATURE - 该数字表示主要功能发布,并且在每个功能发布后都会增加 1。对于 Java 10,该值为 10。
$INTERIM - 该数字表示任何包含错误修复和增强功能的非功能、非更新版本。此版本没有任何不兼容的更改、任何 API 删除或对标准 API 的更改。功能发布后,此计数器将为 0。
$UPDATE - 此数字表示功能发布后完成的更新版本。例如,2018 年 4 月的 Java 更新版本是 JDK 10.0.1,2018 年 7 月的更新版本是 JDK 10.0.2,依此类推。
$PATCH - 该数字表示仅在紧急情况下升级关键问题时才增加的任何紧急版本。
例子
以下程序显示了 JAVA 10 的版本控制详细信息。
public class Tester { public static void main(String[] args) { Runtime.Version version = Runtime.version(); System.out.printf(" feature: %s%n interim: %s%n update: %s%n patch: %s%n", version.feature(), version.interim(), version.update(), version.patch()); } }
输出
它将打印以下输出。
feature: 10 interim: 0 update: 2 patch: 0
Java 10 - 局部变量类型推断
JEP 286 - 局部变量类型推断
局部变量类型推断是 Java 10 以来最明显的语言变化之一。它允许使用 var 定义变量而不指定它的类型。编译器使用提供的值推断变量的类型。这种类型推断仅限于局部变量。
声明局部变量的旧方法。
String name = "Welcome to tutorialspoint.com";
声明局部变量的新方法。
var name = "Welcome to tutorialspoint.com";
现在,编译器通过检查提供的值将 name 变量的类型推断为 String。
值得注意的点
成员变量、方法参数、返回值不进行类型推断。
局部变量应在声明时初始化,否则编译器将无法推断并抛出错误。
局部变量推断可在循环语句的初始化块内使用。
没有运行时开销。由于编译器根据提供的值推断类型,因此不会有性能损失。
没有动态类型变化。一旦推断出局部变量的类型,就无法更改。
使用局部变量类型推断可以减少复杂的样板代码。
Map<Integer, String> mapNames = new HashMap<>(); var mapNames1 = new HashMap<Integer, String>();
例子
以下程序展示了 JAVA 10 中局部变量类型推断的使用。
import java.util.List; public class Tester { public static void main(String[] args) { var names = List.of("Julie", "Robert", "Chris", "Joseph"); for (var name : names) { System.out.println(name); } System.out.println(""); for (var i = 0; i < names.size(); i++) { System.out.println(names.get(i)); } } }
输出
它将打印以下输出。
Julie Robert Chris Joseph Julie Robert Chris Joseph
Java 10 - 新 API 和选项
JDK 10 版本向 Java 库添加了 70 多个新 API 和选项。以下是引入的一些重要增强功能。
可选.orElseThrow() 方法
java.util.Optional 类中提供了一个新方法orElseThrow() ,它现在是get()方法的首选替代方法。
用于创建不可修改集合的 API
List、Set 和 Map 接口中提供了一种新方法copyOf() ,它可以从现有集合实例创建新的集合实例。Collector 类具有新方法toUnmodifyingList()、toUnmodifyingSet() 和 toUnmodifyingMap(),用于将流的元素获取到不可修改的集合中。
禁用 JRE 上次使用情况跟踪
引入了一个新标志 jdk.disableLastUsageTracking,它禁用正在运行的 VM 的 JRE 最后使用情况跟踪。
哈希密码
jmxremote.password 文件中可用的纯文本密码现在被 JMX 代理用其 SHA3-512 哈希值覆盖。
javadoc 对多个样式表的支持
javadoc 命令可以使用一个新选项 --add-stylesheet。此选项支持在生成的文档中使用多个样式表。
javadoc 对重写方法的支持
javadoc 命令可以使用一个新选项 --overridden-methods=value。许多类会重写继承的方法,但不会更改规范。--overridden-methods=value 选项允许将这些方法与其他继承的方法分组,而不是再次单独记录它们。
javadoc 对摘要的支持
新的内联标记 {@summary ...} 可用于指定用作 API 描述摘要的文本。默认情况下,API 描述的摘要是从第一句话推断出来的。
例子
以下程序展示了 JAVA 10 中一些新 API 的使用。
import java.util.List; import java.util.stream.Collectors; public class Tester { public static void main(String[] args) { var ids = List.of(1, 2, 3, 4, 5); try { // get an unmodifiable list List<Integer> copyOfIds = List.copyOf(ids); copyOfIds.add(6); } catch(UnsupportedOperationException e){ System.out.println("Collection is not modifiable."); } try{ // get an unmodifiable list List<Integer> evenNumbers = ids.stream() .filter(i -> i % 2 == 0) .collect(Collectors.toUnmodifiableList());; evenNumbers.add(6); }catch(UnsupportedOperationException e){ System.out.println("Collection is not modifiable."); } } }
输出
它将打印以下输出。
Collection is not modifiable. Collection is not modifiable.
Java 10 - 删除的功能和选项
JDK 10 版本已从 Java 库中删除了多个已弃用的 API、功能和选项。以下为相关详情。
删除了不支持的 LookAndFeels - 使用 Nimbus 或 Aqua LookAndFeels 的应用程序必须迁移到新语法。
Nimbus - 现有代码
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
Nimbus - 新代码
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
Aqua - 现有代码
javax.swing.UIManager.setLookAndFeel("apple.laf.AquaLookAndFeel");
Aqua - 新代码
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Runtime.getLocalizedInputStream 和 getLocalizedOutputStream 方法已删除- Runtime.getLocalizedInputStream 和 getLocalizedOutputStream 方法不再可用,因为它们是过时的国际化机制的一部分。
删除了 RMI 服务器端多路复用协议支持- RMI 服务器端多路复用协议在 Java 9 中被禁用,并在 Java 10 中被删除。
删除了常见 DOM API - com.sun.java.browser.plugin2.DOM 和 sun.plugin.dom.DOMObject API 已被删除。netscape.javascript.JSObject 可用于修改 DOM。
FlatProfiler 已删除- FlatProfiler 在 Java 9 中已弃用,并在 Java 10 中被删除。
已删除过时的 -X 选项- -Xoss、-Xsqnopause、-Xoptimize、-Xboundthreads 和 -Xusealtsigs,过时的 Hotspot VM 选项已在 java 10 中删除。
HostServicesgetWebContext 方法已删除- HostServicesgetWebContext 方法在 Java 9 中已弃用,并在 Java 10 中删除。
删除了 T2K 光栅器和 ICU 布局引擎- T2K 光栅器和 ICU 布局引擎已从 JavaFX 中删除。
VP6/FXM/FLV 代码已删除- P6 视频编码格式和 FXM/FLV 容器支持已在 JavaFX Media 中删除。将改用 MP4 容器中的 H.264/AVC1 或 HTTP Live Streaming。
1.2 版之前的 SecurityManager 方法和字段已删除- 1.2 版之前已弃用的 java.lang.SecurityManager 方法和字段(标记为 forRemoval=true)已被删除。
已删除policytool -policytool安全工具已被删除。
com.sun.security.auth.** 中已弃用的类已删除
以下已弃用的类已被删除
com.sun.security.auth.PolicyFile
com.sun.security.auth.SolarisNumericGroupPrincipal
com.sun.security.auth.SolarisNumericUserPrincipal
com.sun.security.auth.SolarisPrincipal
com.sun.security.auth.X500Principal
com.sun.security.auth.module.SolarisLoginModule
com.sun.security.auth.module.SolarisSystem
旧(JDK 6、JDK 7 和 JDK 8 时代)标准 Doclet 已删除- 旧(JDK 6、JDK 7 和 JDK 8 时代)标准 doclet 用于输出 HTML 内容,并已被替代品取代,已被删除。
javah 工具已删除- 本机标头生成工具 javah 已被删除。
Java 启动器的数据模型选项 -d32 和 -d64 已删除。− 已删除过时和已弃用的选择选项(-d32、-d64、-J-d32 和 -J-d64)。
Java 10 - 已弃用的功能和选项
JDK 10 版本已弃用 Java 库中的多个 API、功能和选项。以下为相关详情。
SNMP 监控支持已弃用- 支持 SNMP 监控和 JVM 管理支持的 jdk.snmp 模块现已弃用,并标记为 forRemoval=true。
java.security 类已弃用- java.security.{Certificate, Identity, IdentityScope, Signer} 类现已弃用,并标记为 forRemoval=true。
javax.security.auth.Policy API forRemoval - 已弃用的 javax.security.auth.Policy 标记为 forRemoval=true。
标记为删除的 API - 以下 API 也标记为在 Java 10 版本中删除,因为独立实现很容易获得。
java.activation
java.corba
java.se.ee(聚合器)
java.transaction
java.xml.绑定
java.xml.ws
java.xml.ws.annotation
Java 10 - JIT 编译器
JEP 317 - 基于 Java 的实验性 JIT 编译器
JIT编译器是用C++编写的,用于将Java转换为字节码。现在,Java 10 可以选择启用基于 Java 的实验性 JIT 编译器 Graal,而不是使用标准 JIT 编译器。Graal 使用 JVMCI(Java 9 中引入的 JVM 编译器接口)。Graal 也可在 Java 9 中使用。借助 Java 10,我们可以启用 Graal 来测试和调试实验性 JVM 编译器。
句法
java -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
Graal 编译器是基于 C++ 的早期编译器的完全重写,针对基于 Linux/x64 的平台。Graal 是在 Java 9 中引入的,作为目前使用的 JIT 编译器的替代方案。Graal 是 JVM 的插件,可以动态插入。它还支持多语言解释。
风险和假设
由于 Graal 是实验性的,并且需要考虑各种热点和具有各种标志选项的 jdk 测试来进行测试工作。与标准 JIT 提前编译器相比,它可能无法通过某些性能基准测试。
Java 10 - 类数据共享
JEP 310 - 应用程序类数据共享
当 JVM 启动时,它会将类加载到内存中作为预备步骤。如果有多个具有多个类的 jar,则第一个请求会出现明显的滞后。在无服务器架构中,这种滞后可能会延迟启动时间,而启动时间是此类架构中的关键操作。应用程序类数据共享概念有助于减少应用程序的启动时间。Java 具有现有的 CDS(类数据共享)功能。通过应用程序类数据共享,Java 10 允许将应用程序类放入共享存档中。通过在多个 java 进程之间共享公共类元数据,可以减少应用程序的启动和占用空间。
过程
应用程序类数据共享过程分为 3 个步骤。
创建要归档的类列表- 使用 Java Launcher 创建位于welcome.jar 中的类 Greeting.java 的welcome.lst 列表。
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=welcome.lst -cp welcome.jar Greeting
创建 AppCDS 存档- 存档用于应用程序类数据共享的类列表。
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=welcome.lst -XX:SharedArchiveFile=welcome.jsa -cp welcome.jar
使用 AppCDS 存档- 使用 java 启动器时使用 AppCDS 存档。
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=welcome.jsa -cp welcome.jar Greeting
Java 10 - 增强的垃圾收集
JEP 304 - 垃圾收集器接口
在 Java 10 之前,GC(垃圾收集器)实现组件分散在代码库中,并且不易替换。Java 10 引入了 Garbage-Collector 接口,以便可以插入替代的 GC 实现。它还有助于将代码库与不同的垃圾收集实现隔离。此功能是 JEP 304 的一部分。
JEP 307 - G1 的并行完整 GC
Java 9 引入了 G1(Garbage First)垃圾收集器。G1 避免了完全垃圾收集,但如果并发线程寻找收集并且内存恢复速度不够快,用户体验就会受到影响。在 Java 10 中,现在 G1 将使用回退完整垃圾收集。
通过这一更改,G1 通过并行使用 Full GC 改善了最坏情况下的延迟。目前,G1使用单线程标记-清除-压缩算法。使用 JEP 307,并行线程将启动标记-扫描-紧凑算法。可以使用以下选项控制线程数。
$java -XX:ParallelGCThreads=4
Java 10 - 区域设置增强
JEP 314 - Unicode 语言标签扩展
Java 7 引入了对BCP 47语言标签的支持。但这种 unicode 区域设置扩展仅限于日历和数字。在 Java 10 中,更新了java.util.Locale和相关类,以实现LDML 规范中指定的其他 unicode 扩展。添加了以下附加扩展。
cu - 货币类型
fw - 一周的第一天
rg - 区域覆盖
tz - 时区
以下 API 已更新。
java.text.DateFormat::get*Instance java.text.DateFormatSymbols::getInstance java.text.DecimalFormatSymbols::getInstance java.text.NumberFormat::get*Instance java.time.format.DateTimeFormatter::localizedBy java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern java.time.format.DecimalStyle::of java.time.temporal.WeekFields::of java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek} java.util.Currency::getInstance java.util.Locale::getDisplayName java.util.spi.LocaleNameProvider
Java 10 - 堆分配
JEP 316 - 替代内存设备上的堆分配
通过 Java 10 中的这一增强功能,现在用户可以指定替代内存设备,例如 NV-DIMM 到 HotSpot VM 来分配 java 堆空间。用户需要使用新选项 -XX:AllocateHeapAt 传递文件系统的路径。
-XX:AllocateHeapAt=~/etc/heap
此选项采用文件路径并进行内存映射以获得所需的结果。其他堆标志(例如 -Xmx、-Xms)继续有效。
Java 10 - 统一的 JDK 森林
JEP 296 - 将 JDK 森林合并为单一存储库
在 JDK 9 中,有八个基于模块的目录,称为 repos。
根
科尔巴
热点
贾克斯普
贾克斯
jdk
语言工具
纳肖恩
代码的组织方式如下:
$ROOT/jdk/src/java.base ... $ROOT/langtools/src/java.compiler ...
从 Java 10 开始,JDK 森林被组织到单个存储库中以简化开发。现在代码组织为 -
$ROOT/src/java.base $ROOT/src/java.compiler ...
Java 10 - 根证书
JEP 319 - 根证书
Cacerts 存储,在 Java 10 之前是一个空集。需要包含一组证书,可用于建立对供应商各种安全协议的证书链的信任。
OpenJDK 版本没有此类证书,这就是为什么 TLS 等关键安全组件在默认版本中不起作用的原因。
现在,由于 Oracle 已经使用 Oracle JAVA SE Root CA 程序开源了根证书,OpenJDK 版本现在可以拥有根证书,从而可以减少 OpenJDK 和 Oracle JDK 之间的差异。
Oracle JAVA SE Root CA 程序颁发根证书。已签署协议的供应商包含在根证书集中。未注册的供应商将包含在下一个版本中。
Java 10 - 线程本地握手
JEP 312 - 线程局部握手
在 JDK 10 中,为 JVM 引入了一个新选项-XX:ThreadLocalHandshakes。此选项仅适用于基于 x64 和 SPARC 的计算机。
此选项可用于提高 VM 性能。它允许在应用程序线程上进行回调,而无需创建全局虚拟机安全点。因此允许 JVM 停止单个线程而不停止所有线程。
由于此选项并非适用于所有平台,其他平台将回退到正常安全点。