同步操作将从 SnailClimb/JavaGuide 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
title | category | tag | |
---|---|---|---|
Java 9 新特性概览 | Java |
|
Java 9 发布于 2017 年 9 月 21 日 。作为 Java 8 之后 3 年半才发布的新版本,Java 9 带来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如集合、Stream
流......。
你可以在 Archived OpenJDK General-Availability Releases 上下载自己需要的 JDK 版本!官方的新特性说明文档地址: https://openjdk.java.net/projects/jdk/ 。
概览(精选了一部分) :
JShell 是 Java 9 新增的一个实用工具。为 Java 提供了类似于 Python 的实时命令行交互工具。
在 JShell 中可以直接输入表达式并查看其执行结果。
JShell 为我们带来了哪些好处呢?
JShell 的代码和普通的可编译代码,有什么不一样?
1 + 1
。模块系统是Jigsaw Project的一部分,把模块化开发实践引入到了 Java 平台中,可以让我们的代码可重用性更好!
什么是模块系统? 官方的定义是:
A uniquely named, reusable group of related packages, as well as resources (such as images and XML files) and a module descriptor。
简单来说,你可以将一个模块看作是一组唯一命名、可重用的包、资源和模块描述文件(module-info.java
)。
任意一个 jar 文件,只要加上一个模块描述文件(module-info.java
),就可以升级为一个模块。
在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具 (Jlink 是随 Java 9 一起发布的新命令行工具。它允许开发人员为基于模块的 Java 应用程序创建自己的轻量级、定制的 JRE),创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。
我们可以通过 exports
关键词精准控制哪些类可以对外开放使用,哪些类只能内部使用。
module my.module {
//exports 公开指定包的所有公共成员
exports com.my.package.name;
}
module my.module {
//exports…to 限制访问的成员范围
export com.·my.package.name to com.specific.package;
}
想要深入了解 Java 9 的模块化,可以参考下面这几篇文章:
在 Java 8 的时候,默认垃圾回收器是 Parallel Scavenge(新生代)+Parallel Old(老年代)。到了 Java 9, CMS 垃圾回收器被废弃了,G1(Garbage-First Garbage Collector) 成为了默认垃圾回收器。
G1 还是在 Java 7 中被引入的,经过两个版本优异的表现成为成为默认垃圾回收器。
增加了List.of()
、Set.of()
、Map.of()
和 Map.ofEntries()
等工厂方法来创建不可变集合(有点参考 Guava 的味道):
List.of("Java", "C++");
Set.of("Java", "C++");
Map.of("Java", 1, "C++", 2);
使用 of()
创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 java.lang.UnsupportedOperationException
异常。
Java 8 及之前的版本,String
一直是用 char[]
存储。在 Java 9 之后,String
的实现改用 byte[]
数组存储字符串,节省了空间。
public final class String implements java.io.Serializable,Comparable<String>, CharSequence {
// @Stable 注解表示变量最多被修改一次,称为“稳定的”。
@Stable
private final byte[] value;
}
Java 9 允许在接口中使用私有方法。这样的话,接口的使用就更加灵活了,有点像是一个简化版的抽象类。
public interface MyInterface {
private void methodPrivate(){
}
}
在 Java 9 之前,我们只能在 try-with-resources
块中声明变量:
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
// omitted
}
在 Java 9 之后,在 try-with-resources
语句中可以使用 effectively-final 变量。
final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) {
// omitted
}
什么是 effectively-final 变量? 简单来说就是没有被 final
修饰但是值在初始化后从未更改的变量。
正如上面的代码所演示的那样,即使 writer
变量没有被显示声明为 final
,但它在第一次被复制后就不会改变了,因此,它就是 effectively-final 变量。
Stream
中增加了新的方法 ofNullable()
、dropWhile()
、takeWhile()
以及 iterate()
方法的重载方法。
Java 9 中的 ofNullable()
方 法允许我们创建一个单元素的 Stream
,可以包含一个非空元素,也可以创建一个空 Stream
。 而在 Java 8 中则不可以创建空的 Stream
。
Stream<String> stringStream = Stream.ofNullable("Java");
System.out.println(stringStream.count());// 1
Stream<String> nullStream = Stream.ofNullable(null);
System.out.println(nullStream.count());//0
takeWhile()
方法可以从 Stream
中依次获取满足条件的元素,直到不满足条件为止结束获取。
List<Integer> integerList = List.of(11, 33, 66, 8, 9, 13);
integerList.stream().takeWhile(x -> x < 50).forEach(System.out::println);// 11 33
dropWhile()
方法的效果和 takeWhile()
相反。
List<Integer> integerList2 = List.of(11, 33, 66, 8, 9, 13);
integerList2.stream().dropWhile(x -> x < 50).forEach(System.out::println);// 66 8 9 13
iterate()
方法的新重载方法提供了一个 Predicate
参数 (判断条件)来决定什么时候结束迭代
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
}
// 新增加的重载方法
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
}
两者的使用对比如下,新的 iterate()
重载方法更加灵活一些。
// 使用原始 iterate() 方法输出数字 1~10
Stream.iterate(1, i -> i + 1).limit(10).forEach(System.out::println);
// 使用新的 iterate() 重载方法输出数字 1~10
Stream.iterate(1, i -> i <= 10, i -> i + 1).forEach(System.out::println);
Optional
类中新增了 ifPresentOrElse()
、or()
和 stream()
等方法
ifPresentOrElse()
方法接受两个参数 Consumer
和 Runnable
,如果 Optional
不为空调用 Consumer
参数,为空则调用 Runnable
参数。
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
Optional<Object> objectOptional = Optional.empty();
objectOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Empty!!!"));// Empty!!!
or()
方法接受一个 Supplier
参数 ,如果 Optional
为空则返回 Supplier
参数指定的 Optional
值。
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
Optional<Object> objectOptional = Optional.empty();
objectOptional.or(() -> Optional.of("java")).ifPresent(System.out::println);//java
Java 9 增加了 java.lang.ProcessHandle
接口来实现对原生进程进行管理,尤其适合于管理长时间运行的进程。
// 获取当前正在运行的 JVM 的进程
ProcessHandle currentProcess = ProcessHandle.current();
// 输出进程的 id
System.out.println(currentProcess.pid());
// 输出进程的信息
System.out.println(currentProcess.info());
ProcessHandle
接口概览:
在 Java 9 中的 java.util.concurrent.Flow
类中新增了反应式流规范的核心接口 。
Flow
中包含了 Flow.Publisher
、Flow.Subscriber
、Flow.Subscription
和 Flow.Processor
等 4 个核心接口。Java 9 还提供了SubmissionPublisher
作为Flow.Publisher
的一个实现。
关于 Java 9 响应式流更详细的解读,推荐你看 Java 9 揭秘(17. Reactive Streams )- 林本托 这篇文章。
变量句柄是一个变量或一组变量的引用,包括静态域,非静态域,数组元素和堆外数据结构中的组成部分等。
变量句柄的含义类似于已有的方法句柄 MethodHandle
,由 Java 类 java.lang.invoke.VarHandle
来表示,可以使用类 java.lang.invoke.MethodHandles.Lookup
中的静态工厂方法来创建 VarHandle
对象。
VarHandle
的出现替代了 java.util.concurrent.atomic
和 sun.misc.Unsafe
的部分操作。并且提供了一系列标准的内存屏障操作,用于更加细粒度的控制内存排序。在安全性、可用性、性能上都要优于现有的 API。
System.LoggerFinder
用来管理 JDK 使 用的日志记录器实现。JVM 在运行时只有一个系统范围的 LoggerFinder
实例。我们可以通过添加自己的 System.LoggerFinder
实现来让 JDK 和应用使用 SLF4J 等其他日志记录框架。CompletableFuture
类增强 :新增了几个新的方法(completeAsync
,orTimeout
等)。InputStream
中包含的数据。java.lang.invoke.MethodHandles
中新增了更多的静态方法来创建不同类型的方法句柄。此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。