JAVA9新特性(一)

JAVA9新特性(一)

JAVA9于北京时间2017年9月22日(当地9.21)正式发布,可以在官网上下载到最新的jdk9,但是目前只支持64位操作系统。

所有特性目录:http://blog.csdn.net/diehuang3426/article/details/79233952
知乎有个问题描述的也不错:https://www.zhihu.com/question/65683103/answer/233904009

Java平台级模块系统(Java Platform Module System)

(PS:此页全是Java平台级模板系统,想看其他的,请看JAVA9新特性(二))

什么是Java Module(模块)

模块是代码和数据集合。 它可以包含Java代码和本地代码。 Java代码被组织为一组包含诸如类,接口,枚举和注解等类型的类。 数据可以包括诸如图像文件和配置文件的资源。一个模块不仅仅是一个包的容器。 除了其名称,模块定义包含以下内容:

  • 所需的其他模块(或依赖于)的列表
  • 导出的软件包列表(其公共API),其他模块可以使用
  • 开放的软件包(其整个API,公共和私有)到其他反射访问模块的列表
  • 使用的服务列表(或使用java.util.ServiceLoader类发现和加载)
  • 提供的服务的实现列表

在使用这些模块时,可以使用这些方面中的一个或多个。
这里写图片描述
Java SE 9平台规范将平台划分为称为平台模块的一组模块。 Java SE 9平台的实现可能包含一些或所有平台模块,从而提供可扩展的Java运行时。 标准模块的名字是以Java 为前缀。Java SE标准模块的示例有java.base,java.sql,java.xml和java.logging。 支持标准平台模块中的API,供开发人员使用。

JavaFX不是Java SE 9平台规范的一部分。 但是,在安装JDK/JRE时,会安装与JavaFX相关的模块。 JavaFX模块名称以javafx为前缀。 JavaFX模块的示例是javafx.base,javafx.controls,javafx.fxml,javafx.graphics和javafx.web。

作为Java SE 9平台的一部分的java.base模块是原始模块。 它不依赖于任何其他模块。 模块系统只知道java.base模块。 它通过模块中指定的依赖关系发现所有其他模块。 java.base模块导出核心Java SE软件包,如java.lang,java.io,java.math,java.text,java.time,java.util等。

在JDK 9中,如果一个模块依赖于另一个模块,并且运行应用程序时第二个模块丢失,则在启动时将会收到一个错误,而不是应用程序运行后的某个时间。 这是一个可靠的基础配置。

模块的目标

模块系统的开发具有三大目标:可靠的配置,强封装,模块化JDK/JRE。这些目标是解决Java 9之前开发和部署Java应用程序所面临的问题。

可靠的配置解决了用于查找类型的容易出错的类路径机制的问题。 模块必须声明对其他模块的显式依赖。 模块系统验证应用程序开发的所有阶段的依赖关系 —— 编译时,链接时和运行时。 假设一个模块声明对另一个模块的依赖,并且第二个模块在启动时丢失。 JVM检测到依赖关系丢失,并在启动时失败。 在Java 9之前,当使用缺少的类型时,这样的应用程序会生成运行时错误(不是在启动时)。

强大的封装解决了类路径上跨JAR的公共类型的可访问性问题。 模块必须明确声明其中哪些公共类型可以被其他模块访问。 除非这些模块明确地使其公共类型可访问,否则模块不能访问另一个模块中的公共类型。 Java 9中的公共类型并不意味着程序的所有部分都可以访问它。 模块系统增加了更精细的可访问性控制。

模块化JDK/JRE使得开发和维护更加简单。例如JRE有一个超级大rt.jar(例如,Java 8的rt.jar中有65M),运行一个hello world,你也需要一个数百兆的JRE环境,如果在J2EE环境,情况将变得复杂无比。把庞大冗余的Java锯成一个个的Module,改进了Java SE 平台,使其可以适应不同大小的计算设备,并改进其安全性,可维护性,提高性能。
这里写图片描述

模块语法

这里写图片描述
< module-statement >是一个模块语句。 模块声明中可以包含零个或多个模块语句。 如果它存在,它可以是五种类型的语句之一:
导出语句(exports statement);
开放语句(opens statement);
需要语句(requires statement);
使用语句(uses statement);
提供语句(provides statement)。

模块命名

模块名称可以是Java限定标识符。 合法标识符是一个或多个由点分隔的标识符,例如policy,com.jdojo.common和com.jdojo.util。 如果模块名称中的任何部分不是有效的Java标识符,则会发生编译时错误。 例如,com.jdojo.common.1.0不是有效的模块名称,因为名称中的1和0不是有效的Java标识符。与包命名约定类似,使用反向域名模式为模块提供唯一的名称。 使用这个惯例,名为com.jdojo.common的最简单的模块可以声明如下:
这里写图片描述
模块名称不会隐藏具有相同名称的变量,类型和包。 因此,可以拥有一个模块以及具有相同名称的变量,类型或包。 他们使用的上下文将区分哪个名称是指什么样的实体。
在JDK 9中, open, module, requires, transitive, exports, opens, to, uses, provides 和 with是受限关键字。只有当具体位置出现在模块声明中时,它们才具有特殊意义。 可以将它们用作程序中其他地方的标识符。 例如,以下模块声明是有效的,即使它不使用直观的模块名称:
这里写图片描述
第一个模块字被解释为一个关键字,第二个是一个模块名称。
你可以在程序中的任何地方声明一个名为module的变量:
这里写图片描述

exports和requires

导出语句将模块的指定包导出到所有模块或编译时和运行时的命名模块列表。 它的两种形式如下:
这里写图片描述
这里写图片描述
需要(require)语句声明当前模块与另一个模块的依赖关系。 一个名为M的模块中的“需要N”语句表示模块M取决于(或读取)模块N。语句有以下形式:
这里写图片描述
require语句中的静态修饰符表示在编译时的依赖是强制的,但在运行时是可选的。requires static N语句意味着模块M取决于模块N,模块N必须在编译时出现才能编译模块M,而在运行时存在模块N是可选的。require语句中的transitive修饰符会导致依赖于当前模块的其他模块具有隐式依赖性。假设有三个模块P,Q和R,假设模块Q包含requires transitive R语句,如果如果模块P包含包含requires Q语句,这意味着模块P隐含地取决于模块R。
这里写图片描述
下图描述了两个名为policy和claim的模块之间的依赖关系。 policy模块包含两个名为pkg1和pkg2的包,它导出包pkg1,该包使用虚线边界显示,以将其与未导出的包pkg2区分开来。 claim模块包含两个件包pkg3和pkg4,它不导出包。 它声明了对policy模块的依赖。
这里写图片描述
这里写图片描述

open

如果你的模块依赖于另一个模块,则该模块声明要求知道模块名称。一些Java框架和工具(Spring,Hibernate…)在很大程度上依赖于反射来在运行时访问未导出的模块的代码
当模块导出软件包时,依赖于第一个模块的其他模块只能访问导出的软件包中的公共API。 在运行时,在模块的所有软件包上授予深入的反射访问权限(访问公共和私有API),可以声明一个开放的模块。

这里写图片描述
这里写图片描述
开放语句允许对所有模块的反射访问指定的包或运行时指定的模块列表。 其他模块可以使用反射访问指定包中的所有类型以及这些类型的所有成员(私有和公共)。 开放语句如同exports形式
这里写图片描述
导出语句允许仅在编译时和运行时访问指定包的公共API,而打开语句允许在运行时使用反射访问指定包中的所有类型的公共和私有成员。

uses和provides

Java允许使用服务提供者和服务使用者分离的服务提供者机制。 JDK 9允许使用语句(uses statement)和提供语句(provides statement)实现其服务。
使用语句可以指定服务接口的名字,当前模块就会发现它,使用 java.util.ServiceLoader类进行加载。格式如下:
这里写图片描述
这里写图片描述
com.jdojo.PrimeChecker是一个服务接口,其实现类将由其他模块提供。 模块M将使用java.util.ServiceLoader类来发现和加载此接口的实现。
提供语句指定服务接口的一个或多个服务提供程序实现类。 它采取以下形式:
这里写图片描述
相同的模块可以提供服务实现,可以发现和加载服务。 模块还可以发现和加载一种服务,并为另一种服务提供实现。
这里写图片描述

模块的访问权限

模块之间的关系被称作readability(可读性),代表一个模块是否可以找到这个模块文件,并且读入系统中(注意:并非代表可以访问其中的类型)。在实际的代码,一个类型对于另外一个类型的调用,我们称之为可访问性(Accessible),这意味着可以使用这个类型; 可访问性的前提是可读性,换句话说,先有模块可读,然后才能再进一步检测可访问性(安全)。
这里写图片描述
这里写图片描述

类加载器查找类方式改变

在这三个级别的Loader下面有一个统一Module 管理,用于控制和管理模块间的依赖关系,可读性,可访问性等。ClassLoader在Java 9中的类装载逻辑和之前一样,但是,通过模块管理系统,ClassLoader.FindClass的能力,将被限制在readable&accessible的条件下,而不是之前的简单的Public条件。
这里写图片描述

PS:此文章为网络糅合编写,侵删。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值