Java 8 发布三年多以后,java9已经发布了 。 你可能已经据说过 Java 9 的模块系统,可是这个新版本还有许多其它的更新。 这里有九个使人兴奋的新功能将与 Java 9 一块儿发布。java
Java 8 发布三年多以后,java9已经发布了 。 你可能已经据说过 Java 9 的模块系统,可是这个新版本还有许多其它的更新。 这里有九个使人兴奋的新功能将与 Java 9 一块儿发布。java
Java 9 的定义功能是一套全新的模块系统。当代码库愈来愈大,建立复杂,盘根错节的“意大利面条式代码”的概率呈指数级的增加。这时候就得面对两个基础的问题: 很难真正地对代码进行封装, 而系统并无对不一样部分(也就是 JAR 文件)之间的依赖关系有个明确的概念。每个公共类均可以被类路径之下任何其它的公共类所访问到, 这样就会致使无心中使用了并不想被公开访问的 API。此外,类路径自己也存在问题: 你怎么知晓全部须要的 JAR 都已经有了, 或者是否是会有重复的项呢? 模块系统把这俩个问题都给解决了。正则表达式
模块化的 JAR 文件都包含一个额外的模块描述器。在这个模块描述器中, 对其它模块的依赖是经过 “requires” 来表示的。另外, “exports” 语句控制着哪些包是能够被其它模块访问到的。全部不被导出的包默认都封装在模块的里面。以下是一个模块描述器的示例,存在于 “module-info.java” 文件中:shell
module blog { exports com.pluralsight.blog; requires cms; }
咱们能够以下展现模块:编程
请注意,两个模块都包含封装的包,由于它们没有被导出(使用橙色盾牌可视化)。 没有人会偶然地使用来自这些包中的类。Java 平台自己也使用本身的模块系统进行了模块化。经过封装 JDK 的内部类,平台更安全,持续改进也更容易。安全
当启动一个模块化应用时, JVM 会验证是否全部的模块都能使用,这基于 `requires` 语句——比脆弱的类路径迈进了一大步。模块容许你更好地强制结构化封装你的应用并明确依赖。你能够在这个课程中学习更多关于 Java 9 中模块工做的信息 。模块化
当你使用具备显式依赖关系的模块和模块化的 JDK 时,新的可能性出现了。你的应用程序模块如今将声明其对其余应用程序模块的依赖以及对其所使用的 JDK 模块的依赖。为何不使用这些信息建立一个最小的运行时环境,其中只包含运行应用程序所需的那些模块呢? 这能够经过 Java 9 中的新的 jlink 工具实现。你能够建立针对应用程序进行优化的最小运行时映像而不须要使用彻底加载 JDK 安装版本。工具
许多语言已经具备交互式编程环境,Java 如今加入了这个俱乐部。您能够从控制台启动 jshell ,并直接启动输入和执行 Java 代码。 jshell 的即时反馈使它成为探索 API 和尝试语言特性的好工具。学习
测试一个 Java 正则表达式是一个很好的说明 jshell 如何使您的生活更轻松的例子。 交互式 shell 还能够提供良好的教学环境以及提升生产力。在教人们如何编写 Java 的过程当中,再也不须要解释 “public static void main(String [] args)” 这句废话。测试
一般,您但愿在代码中建立一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 “add” 调用,使得代码重复。 Java 9,添加了几种集合工厂方法:
Set<Integer> ints = Set.of(1, 2, 3); List<String> strings = List.of("first", "second");
除了更短和更好阅读以外,这些方法也能够避免您选择特定的集合实现。 事实上,从工厂方法返回已放入数个元素的集合实现是高度优化的。这是可能的,由于它们是不可变的:在建立后,继续添加元素到这些集合会致使 “UnsupportedOperationException” 。
长期以来,Stream API 都是 Java 标准库最好的改进之一。经过这套 API 能够在集合上创建用于转换的申明管道。在 Java 9 中它会变得更好。Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable。还有个 iterate 方法的新重载方法,可让你提供一个 Predicate (判断条件)来指定何时结束迭代:
IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);
第二个参数是一个 Lambda,它会在当前 IntStream 中的元素到达 100 的时候返回 true。所以这个简单的示例是向控制台打印 1 到 99。
除了对 Stream 自己的扩展,Optional 和 Stream 之间的结合也获得了改进。如今能够经过 Optional 的新方法 `stram` 将一个 Optional 对象转换为一个(多是空的) Stream 对象:
Stream<Integer> s = Optional.of(1).stream();
在组合复杂的 Stream 管道时,将 Optional 转换为 Stream 很是有用。
Java 8 为咱们带来了接口的默认方法。 接口如今也能够包含行为,而不只仅是方法签名。 可是,若是在接口上有几个默认方法,代码几乎相同,会发生什么状况? 一般,您将重构这些方法,调用一个可复用的私有方法。 但默认方法不能是私有的。 将复用代码建立为一个默认方法不是一个解决方案,由于该辅助方法会成为公共API的一部分。 使用 Java 9,您能够向接口添加私有辅助方法来解决此问题:
public interface MyInterface { void normalInterfaceMethod(); default void interfaceMethodWithDefault() { init(); } default void anotherDefaultMethod() { init(); } // This method is not part of the public API exposed by MyInterface private void init() { System.out.println("Initializing"); } }
若是您使用默认方法开发 API ,那么私有接口方法可能有助于构建其实现。
Java 9 中有新的方式来处理 HTTP 调用。这个迟到的特性用于代替老旧的 `HttpURLConnection` API,并提供对 WebSocket 和 HTTP/2 的支持。注意:新的 HttpClient API 在 Java 9 中以所谓的孵化器模块交付。也就是说,这套 API 不能保证 100% 完成。不过你能够在 Java 9 中开始使用这套 API:
HttpClient client = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.google.com")) .header("User-Agent","Java") .GET() .build(); HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());
除了这个简单的请求/响应模型以外,HttpClient 还提供了新的 API 来处理 HTTP/2 的特性,好比流和服务端推送。