返回 登录
0

新的Java 9功能一目了然

过去3年多,我们一直在等待这一刻,但现在终于到了 - Java 9已经发布了。在本文中,Henning Schwentner介绍了新版本的功能。

新的模块化系统:Java中的项目拼图9

使用版本8,Java确实获得了很多新功能,其中Lambdas的支持肯定是最大的影响。此外,对集合和新的日期时间API的启用的批量操作改进了Java开发人员的日常生活。然而,长期以来想要的功能尚未成为Java 8,并成为新发布的Java 9版本的商标- 使用Project Jigsaw进行模块化。

项目拼图解决了迄今为止影响Java的两个问题,即“JAR地狱”,并且在类之上缺少强大的封装机制。从一开始,Java就有了一个包构造。一个类可以包含一个包中的两个可见性级别之一。无论是公开的,在这种情况下,可以从任何地方访问该类。如果它不是公共的,它只能从包中进行访问。

但是包不能嵌套。因此,您或者拥有非结构化的“大泥巴” - 包裹或仅由公共课程组成的包。JAR(Java Archives)只是一组公共类文件加数据。它们不是组件,不提供封装。因此,它们没有接口,或者JAR的接口是JAR所包含的接口,因为由于缺少封装,它不能从外部访问中隐藏任何内容。

第9版给Java定义模块的可能性。一个模块是一个命名的,自描述的程序组件,由一个或多个包(和数据)组成。模块可以定义如清单1所示。

模块 de module .a { exports de。module .a.paket.x;}模块 de module .b { exports de。module .a.paket.y; 出口德 module .a.paket.z;}模块 de module .c { requires de。模块 .a 需要 de 模块 .b}
该接口定义指示模块向外部世界提供哪些包(使用关键字exports)以及外部需要哪些模块(需要关键字)。注意:这不是前一句中的错字; 一个模块导出包,但需要模块。这可能会令人困惑,因为软件包和模块通常具有相同或非常相似的名称。未明确导出的模块的所有软件包只能在模块中使用。如果您尝试从模块外部访问它们,则会发生编译器错误。

使用模块化JAR作为模块

现在我们已经看到了如何声明一个模块,让我们回答另一个问题:我们在哪里编写模块声明?该约定表示您在名为module-info.java的源代码文件中声明它,并将其放在模块的文件层次结构的根目录下。然后,编译器将其转换为文件module-info.class。名称“module-info”包含连字符,因为它是一个无效的类名。这样,现有的代码就不会被损坏。然后将Java文件称为模块声明和类文件模块描述符。

如果您以这种方式声明了一个模块,则可以从中创建一个模块化的JAR。它的结构就像一个常规的JAR文件,区别在于它的根目录下有一个module-info.class文件。这样的模块化JAR可以用作模块。由于向下兼容的原因,它也可以用作经典的JAR文件和类路径。那么module-info.class就被忽略了。说到类路径:通过引入模块概念,它是由一个替代ModulePath进行。在模块路径中,您可以指定在文件系统中找到特定模块的位置。

在过去,有一个类路径,一堆JAR无序,可以不可控制地使用对方。此外,JAR内的所有内容都可以访问。现在我们可以使用模块机制来明确定义哪个模块应该使用哪些模块。这使得可以使用相同库并行的多个版本。例如,模块A可以使用版本1中的库,版本2中的模块B,最后,模块C可以使用两个模块A和B.

使用Java 9的域驱动设计

通过模块概念,可以更好地表达软件架构。例如,层可以表示为模块,并且它们的界面可以被清楚地定义。编译器可以至少部分地检测并防止架构违规。我们举一个银行应用程序的例子,设计用域驱动的设计(清单2和图1)。

新的Java 9功能一目了然

module de.wps.bankprogramm.domainLayer { exports de.wps.bankprogramm.domainLayer.valueObject; 出口 de.wps.bankprogramm.domainLayer.entity;}module de.wps.bankprogramm.infrastructurelayer { exports de.wps.bankprogramm.infrastructureLayer.database;}module de.wps.bankprogramm.applicationLayer { requires de.wps.bankprogramm.infrastructureLayer; 需要 de.wps.bankprogramm.domainLayer; 出口 de.wps.bankprogramm.applicationLayer.repositories;}module de.wps.bankprogramm.uiLayer { requires de.wps.bankprogramm.domainLayer; 需要 de.wps.bankprogramm.applicationLayer;}
系统的四层被实现为模块。专用逻辑层(即模块domainLayer)的模块被声明为与其他模块没有依赖关系。我们不想依赖技术代码来污染我们的业务代码。它包含一个用于我们系统的实体的包,一个用于它的值对象。的储存库,反过来,可以在基础设施层(模块infrastructureLayer)。因此,在这个设计中,它们被插入到应用层模块(applicationLayer)中。根据上述声明,可以访问基础设施和业务逻辑层。

用户界面层(uiLayer模块)可以访问用户逻辑和应用层。使用数据库访问代码的包将导致编译器错误,因为它在基础设施包中,并且没有在uiLayer的要求中指定。存储库到应用程序层的分配在架构上并不完全清晰,而是在这里完成,以避免使示例过于复杂。

将JDK切成块

模块机制对许多项目很有兴趣,特别是JDK本身。这是项目名称,拼图来自的地方。并用这个拼图Java应该分为模块。到目前为止,整个JRE必须始终交付,即使只运行没有GUI或不访问数据库的小程序。使用Java 9,JRE和JDK分解为模块本身。这允许每个程序定义它需要什么,减少内存使用和提高性能。

Java标准模块包括java.base,java.sql,java.desktop和java.xml。基本模块java.base总是隐式包含 - 就像包java.lang不需要单独导入一样。模块java.base将包含java.lang,java.math和java.io包。对于JDK本身的模块,JAR文件不够,因为它们也必须包含本机代码。因此,这里介绍了所谓的JMOD文件。Java的首席架构师Mark Reinhold的直接引用:“JMOD文件是类固醇的JAR文件”。项目拼图当然是Java 9带来的巨大变化,也是其主要功能。但还有一些其他功能将使开发人员的生活更轻松。

Java 9中还会发生什么

许多编程语言都有一个读取 - 打印循环(REPL),即一种直接执行该语言代码并输出结果的命令行。Java在标准的JDK中没有这样的东西。有第三方产品,如BeanShell或Java REPL,以及IntelliJ IDEA插件。Kulla项目将JShell介绍给JDK - 官方的Java版本REPL。这提供了希望Java将更容易学习。交互式模式可以使程序员比经典的写/编译/执行周期快得多的反馈。

使用Java 9,现在有命令行的CLI程序jshell。还提供了一个API,以便其他应用程序可以使用此功能。对于要在Eclipse中使用JShell的IDE制造商来说,这是特别有趣的,NetBeans和Co.可以安装。

支持Unicode

存在Unicode以对不同语言的字符进行编码。该标准不断扩展,最后两个版本7.0和8.0尚不支持Java。Unicode 7.0包含对双向文本的改进,即包含拉丁字母和非拉丁字符的部分。

例如,使用8.0版,emojis是以不同肤色和新的面孔,如圣诞节母亲的表情扩展的。此外,单独的JEP(第226号)允许您以UTF-8保存属性文件。以前只支持ISO 8859-1作为编码。该资源包API扩展用于这一目的。

轻松创建收藏

使用数组一次定义几个对象并不难。

String [] firstnames = { “Joe”,“Bob”,“Bill” };
不幸的是,这不是很容易收藏,但是。要创建一个小的,不可改变的集合,必须构造和分配它,然后添加元素,最后构建一个周围的包装器。

列表firsnamesList = new ArrayList <>();firstnamesList。add(“Joe”);firstnamesList。add(“Bob”);firstnamesList。add(“Bill”);firstnamesList = Collections.unmodifiableList(firstnamesList);
我们没有一行代码,而是一行五行。此外,它不能表达为单个表达式。有几种选择,例如Arrays.asList(),但是如果要定义大量的值,则需要很长时间:

设置 firstnamesQuantity = Collections.unmodifiableSet( new HashSet(Arrays.asList(“Joe”,“Bob”,“Bill”)));
Java 9因此引入了方便的方法,这使得类似的事情更容易表达。

列表 firsnamesList = 列表 .of( “ 乔”,“鲍勃”,“比尔”);
使用变量,可以将不同数量的参数传输到这些工厂方法。此功能可用于集合和列表,也可用于Map的类似形式。由于Java 8中接口的方法实现,所谓的默认方法,可以直接在List,Set和Map的接口内定义这些方便方法。

Java 9中的HTTP / 2支持

HTTP,用于传输网页的协议,早在1997年就被采用在目前的1.1版本中。直到2015年,新版本2才成为标准。新版本的目标是减少延迟,从而允许更快地加载网页。这是通过各种技术实现的:

标题压缩
服务器推送
流水线
通过TCP连接复用多个HTTP请求
同时,与HTTP 1.1的兼容性仍然保持不变。大部分语法甚至保持不变; 例如,方法(GET,PUT,POST等),URI,状态代码和头字段。

Java将具有实现JEP 110的HTTP / 2开箱即用的支持。此外,过时的HttpURLConnection -API正在被替换。它是在HTTP 1.0的时代创建的,并使用了协议无关的方法。这适合九十年代,因为目前还不确定HTTP的成功率。然而,如今,对Gopher的支持并不重要。ALPN也得到支持。在新世界,您可以使用当代Fluent-API。

HttpResponse response = HttpRequest .create(new URI(“http://www.javamagazin.de”) 。体(一个人()) 。GET() 。发送();
所得到的HTTP响应可用于查询状态代码和内容:

int statusCode = response .responseCode();String body = response .body(asString());
减少内存消耗与紧凑的字符串

从版本1开始,Java中的字符串将使用java.lang.String类显示。从一开始,这个类包含一个char数组。该数据类型在Java中占用两个字节。这样可以轻松地在UTF-16中显示字符,而不仅仅是支持拉丁字母。然而,许多应用程序只使用来自Latin-1编码的字符,它只需要一个字节。在这种情况下,每隔一个字节是空的,并且浪费了内存空间。

因此,JEP 254引入了String类的一个实现,它包含一个字节数组加上一个编码字段而不是一个字符数组。编码字段指定字符串是否包含占用每个两个字节的UTF-16字符的经典序列,或者每个占用一个字节的拉丁字母序列。创建相应字符串的编码应由字符串内容自动识别。

这个优化的愉快之处在于您可以自动从中受益。实际上,它只是一个实现细节,与旧的Java版本保持100%的兼容性。因此,使用许多字符串的应用程序将通过简单地安装最新版本的Java来显着减少其内存需求。除了String类之外,还调整了相关类(如StringBuilder和StringBuffer)以及HotSpot VM。

Java中的JavaDoc增强功能9

到目前为止,JavaDoc只能在4.01的过时版本中生成HTML。使用Java 9,可以创建HTML5。因此,javadoc命令是指定要生成的HTML代码的版本。相关联的JEP 224的明确的非目标是消除三个帧结构。希望这将在未来的版本中完成。此外,生成的HTML页面将被提供有用于搜索某些Java元素的搜索机制。然后根据“模块”,“包”或“类型”对结果进行分类。

自动缩放HiDPI图形

在Mac上,JDK已经支持视网膜显示,但在Linux和Windows上,它并没有。在那里,Java程序在当前的高分辨率屏幕上可能看起来很小,不能使用它们。这是因为像素用于这些系统的大小计算 - 无论像素实际有多大。毕竟,高分辨率显示器的有趣部分是像素非常小。

JEP 263以这样的方式扩展了JDK,即Windows和Linux也考虑到像素的大小。为此,使用比现在更多的现代API:Direct2D for Windows和GTK +而不是Xlib for Linux。图形,窗口和文本由此自动缩放。JEP 251还提供处理多分辨率图像的能力,即包含不同分辨率的相同图像的文件。根据相应屏幕的DPI度量,然后以适当的分辨率使用图像。

Java 9还有什么?

像任何其他Java版本一样,Java 9包含许多次要的细节和更新。这些包括:

将ARM处理器升级到64位层级的新型ARM架构AArch64现在得到了支持。
从版本1.2开始,Java使用自己的专有格式来存储加密密钥:JKS。JEP 229新增了Java中的标准文件格式PKCS12。
Java 8的更新40引入了垃圾收集器G1(垃圾回收)。Java 9现在将G1提升到标准的垃圾收集器状态。
在Java 8之前,Image I / O框架不支持图像格式TIFF。这将与JEP 262进行更改,javax.imageio将相应地进行扩展。
使用Rhino,Java具有JavaScript执行环境。对于IDE和类似的工具,JEP 236公开释放先前仅在内部可用的解析器API,以访问AST。
前景:Java 9之后?

原来这篇文章最初应该是:“2016年9月,新的Java版本9将被发布”。现在一年以后的事实肯定不会太糟糕,因为许多变化属于“家务”类别。

因此,终于支持当前版本的Unicode和HTTP标准。还有一些微小的变化,使开发人员的生活变得更加容易,比如更方便的创建集合和实现紧凑的字符串。

最重要的功能是项目拼图的模块概念。主要项目和需要较小内存占用的项目都是关键因素,将受益于这一发展。主要项目受益于JAR-hell的问题一方面使用ModulePath解决,另一方面是因为这些系统的架构可以用模块更清楚地表达出来。内存敏感项目受益,因为JDK本身分为多个模块,不再需要整体加载。

1、具有1-5工作经验的,面对目前流行的技术不知从何下手,

需要突破技术瓶颈的。2、在公司待久了,过得很安逸,

但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的。

3、如果没有工作经验,但基础非常扎实,对java工作机制,

常用设计思想,常用java开发框架掌握熟练的。

4、觉得自己很牛B,一般需求都能搞定。

但是所学的知识点没有系统化,很难在技术领域继续突破的。

  1. 群号:高级架构群 606187239备注好信息!

6.阿里Java高级大牛直播讲解知识点,分享知识,

多年工作经验的梳理和总结,带着大家全面、

科学地建立自己的技术体系和技术认知!

评论