首页 > 其他分享 >JTCR-模块-14

JTCR-模块-14

时间:2024-04-22 16:48:47浏览次数:19  
标签:语句 JTCR 依赖 java 14 导出 模块 requires

JDK9 引入了模块,用于描述代码之间的关系和依赖,控制某模块是否可以被其他模块访问。

模块基础

一个模块由一组包和资源组成。模块定义在名为 module-info.java 的文件中,javac 将这个文件编译成类文件,称为 module descriptor。该文件仅能包含一个模块定义。
模块定义的一般形式为:

// name 为模块名,为单个有效标识符或者一组以句号(.)分隔的标识符
module name {
  // 定义,可为空
}

一个模块可以指定它所依赖的模块,使用 requires 关键字,这个依赖关系在编译和运行时检查;一个模块可以控制它的包能否被其他模块访问,需要使用 exports 关键字,包中 public 和 protected 类型只有显式导出才能被其他模块访问。

requires module: 在模块定义中指定了当前模块依赖的模块 module,这条语句执行时,如果 module 模块不存在,则无法编译。可以定义多条该语句。
exports package: 在模块定义中,指定了当前模块导出的包。这条语句执行时,导出当前模块中 package 包。可以定义多条该语句。

模块导出一个包时,该包中所有 public 和 protected 类型都可以被其他模块访问。没有导出的包,里面任何类型在该模块外访问不到。包中 public 和 protected 类型不论是否导出,在包所在的模块中都可以访问。
在依赖关系中,requiresexports 都需要用到。对于依赖模块,必须使用 requires 指明它所依赖的模块,被依赖的模块必须使用 exports 导出依赖模块需要的包。无论哪一方缺失相关的语句,都将不能通过编译。
requiresexports 必须在模块定义中使用,模块定义必须位于名为 module-info.java 的文件中。

java.base 和 platform modules

API 模块称为 platform modules,这些模块都以“java” 作为前缀,如 java.base、java.desktop、java.xml 等。通过将 API 模块化,应用只需要它用到的 API 模块,而不需要整个 JRE,显著减小体积。
API 模块中最重要的是 java.base 模块,里面包含和导出了所有常用的包,如 java.lang、java.io、java.util 等。其他所有模块都可以访问该模块,在模块定义中不需要显式声明 requires java.base,默认添加了。
从 JDK9 开始,Java 文档中写明了包所在的模块。如果该包位于 java.base 中,可以直接使用该包中定义的内容,否则需要使用 requires 声明依赖关系才能使用。

遗留代码和未命名模块

当使用的代码不在命名模块中,则该代码自动属于未命名模块,未命名模块自动导出所有包,同时未命名模块可以访问其他所有模块。
当编译不使用模块的程序时,使用类路径而不是模块路径。
以上两种特性保证了遗留代码(模块使用之前的代码)和使用模块的代码之间的兼容性。
大项目使用模块可以获得好处,如控制访问性;简单程序基本不需要使用模块。

针对特定模块导出

有时候并不想将一个模块中的包导出给所有其他模块使用,这个时候可以使用限定导出(qualified export),一般形式为:exports pkg to modules。其中,modules 指一个或用逗号(,)分隔的一组模块,这些模块可以使用导出的 pkg 包。

requires 传递

当 A requires B,B requires C 时,如果 A 模块既需要 B 导出的包,又需要 C 导出的包,可以声明 A requires C 解决该问题。但是如果类似这种情况很多,这种做法显得冗余。另一种做法称为 implied readability,即在 B 中添加 requres transitive C。这条语句表明任何依赖 B 的语句都自动依赖 C。
transitive 如果后面紧跟一个分隔符会被认为是一个标识符。

使用服务

通过使用插件的方式,可以在不改变应用核心的情况下增强应用的功能。Java 通过 services 和 service providers 提供 pluggable 应用架构。模块系统对此提供了支持。

Java 中,service 是由接口或抽象类定义功能的程序单元,而具体的实现由 service provider 提供。service 提供了 pluggable 架构,例如 service 提供语言的翻译功能,而从某个具体语言翻译成另外一种具体语言由 service provider 实现。

class ServiceLoader<S> 支持 service provider,S 指服务类型。service provider 通过 load() 方法加载,形式之一为:public static <S> ServiceLoader<S> load(Class<S> serviceType)。调用 load() 方法时,返回 ServiceLoader 的实例,该实例支持迭代和循环遍历。
模块使用 provides 语句指定它提供的服务,使用 use 语句指定它需要的服务,同时使用 with 指定需要的 service provider 类型。一般形式为:

// 指定模块提供的服务类型(一般是接口,抽象类也可以)
// implements 是由逗号分隔的多个具体实现
provides serviceType with implements;

// 指定该模块需要的服务类型
use serviceType;

模块图

编译器在解析模块之间的依赖关系时会创建模块图表示依赖,模块图将表示所有相关模块的依赖关系。java.base 不包括在图中,因为自动依赖。

三个模块特性

open 模块的所有包在运行时可以被其他模块访问,无论是否导出。主要用于反射。显式导出的包在编译时可以被其他模块访问,未导出的不能。open 模块定义的一般形式为:

open module Name {
  // 定义
}

open 语句用于指定模块中特定的包可以在运行时被其他所有模块访问,与编译时的访问性无关。open 语句不能在 open 模块中使用,可以使用 to 子句限定允许访问该包的模块。open 语句的一般形式为: open pkg

requires 语句指定编译时和运行时的依赖关系,如果在该语句中使用静态修饰符将指定编译时的依赖关系,不指定运行时的依赖关系。一般形式为:requires static module

JDK9 提供了 jlink 工具,该工具将一组模块打包成运行时 image,在应用根目录的上一级目录中运行

jlink --launcher appName=url/pkg.mainClass
      --module-path javaHome\jmods;root\modules
      --add-modules startSubDir
      --output outputDir

得到打包成的运行时 image。

层和自动化

在模块图中使用同一个类加载器的模块构成模块层(module layers)。不同层使用不同的类加载器。

通过在模块路径中指定 nonmodular JAR 文件可以创建自动模块,自动模块的名字自动获得,也可以在 manifest 文件中指定。正常模块可以依赖自动模块中的代码。

参考

[1] Herbert Schildt, Java The Complete Reference 11th, 2019.

标签:语句,JTCR,依赖,java,14,导出,模块,requires
From: https://www.cnblogs.com/xdreamc/p/16406950.html

相关文章

  • JTCR-lambda 表达式-13
    介绍lambda表达式本质上是一个匿名方法,用于实现函数式接口(functionalinterface)定义的方法。这就产生了匿名类。lambda也称为闭包(closures)。函数式接口是仅有一个抽象方法的接口。如Runnable接口仅有run()方法,该方法表明了接口的目的。函数式接口定义了lambda表达式的目......
  • JTCR-泛型-12
    什么是泛型具有参数化类型的类、接口或方法。具体的类型在运行时才确定。在泛型出现前通过使用Object引用也可以达到泛型的效果,但是缺乏类型安全检查,泛型添加了这一点。简单的泛型例子//T是类型参数,作为实际类型的占位符classGen<T>{Tv;Gen(To){v=o;......
  • JTCR-I/O,Try-with-Resources 及其他-11
    I/O基础Java的I/O操作通过流来实现。流是对输入、输出数据的抽象,每个流都和一个具体的物理实体关联,比如在输入中,流可以和键盘、磁盘文件或者网络输入等关联,虽然每个物理实体不同,但是流可以以同样的方式进行处理。Java定义了字节流和字符流。字节流处理的对象是二进制数据,以......
  • Vinka超低功耗抗干扰LCD液晶段码屏驱动芯片 推出新封装:VKL144C/D LQFP48/SSOP48
    VKL144C/D概述:VKL144C/D是一个点阵式存储映射的LCD驱动器,可支持最大144点(36SEGx4COM)的LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据,可配置4种功耗模式,也可通过关显示和关振荡器进入省电模式。其高抗干扰,低功耗的特性适用于水电气表以及工控仪表类产品。特点•工......
  • CAE实证Vol.14:超大内存机器,让你的HFSS电磁仿真解放天性
     HFSS(HighFrequencyStructureSimulator)是世界上第一款商业化的3D电磁仿真软件。由Ansoft公司在1990年开发并发布第一个版本。2008年,Ansys收购了Ansoft,继续开发HFSS等电子与电磁仿真产品,目标是解决整个工业体系中机械与电气领域的持续融合问题。现在的HFSS,已经成为天线、......
  • SpringBoot模块集成mqtt代码实现
    1//引入pom2<!--mqtt-->3<dependency>4<groupId>org.springframework.boot</groupId>5<artifactId>spring-boot-starter-integration</artifactId>6</dependency>......
  • 常用模块
    20240419模块os模块操作本地路径、操作文件夹创建、删除执行本地cmd命令拼接路径文件路径相关操作--file--表示当前文件所在的文件夹路径importosfile_name=os.path.dirname(__file__)获取当前文件所在的文件路径file_path=os.path.abspath(__f......
  • hashlib模块
    摘要算法:只能加密不能解密加密算法:用方法加密加密后的字符串可以解密【一】什么是摘要算法Python的hashlib提供了常见的摘要算法如MD5SHA1等等。摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表......
  • logging模块
    logging模块记录log记录日志的模块importloggingimportlogging.configimportosimportsystry:#想要给日志上色就安装这个模块#pipinstallcoloredlogs:::>>>给日志上个色importcoloredlogsexceptExceptionase:ifstr(e)=="Nomodulenamed'coloredlo......
  • json模块
    【一】什么是序列化将Python中的字典、列表、元组...转换成字符串类型如果使用str强制转换数据类型,造成的后果就是转换后的字符串无法转回Python对象【二】什么是反序列化将字符串类型的数据转换成Python对象(列表、字典、元组...)能将python对象转为字符串-->字符串......