模块平台系统

1、

  Java SE9的重大特性之一就是模块平台系统,基于兼容性,仍然可以使用基于类路径的方式来组织、建立链接库。比如你有一个Console类,你基于它撰写了链接库以供其他同事使用,但你不想要它直接调用Console类的相关功能,以免他的程序直接依赖在Console类上,这时候就可以使用模块平台系统。模块平台系统即基于模块来管理链接库功能封装、链接库之间的相依性等需求,而这之前我们都是使用基于类路径的方式来组织、建立和使用链接库。有相关的开发工具可以用来处理模块的使用,我们也可以自己手动来建议模块。

  下面是我们自己来手动建立模块的一个示例,比如我们有一个Main类的源文件,它在xsl包下:

  我们在包xsl所在的目录新建一个module-info.java的模块配置文件,并添加如下所示的内容,其中使用module关键字定义了模块名称为main_module:

   然后我们分别使用javac编译Main.java文件和模块配置文件到同一个目录下,这个目录就代表了模块,所以目录名应该设置为main_module:

  main_module模块中的内容如下:

 我们想要执行模块的话可以使用--module-path(缩写为-p)来指定模块所在的路径、--module(缩写为-m)指定模块的可执行类:

2、

   在Java SE9中,如果还是像之前一样使用类路径的话而不是模块的话,这些类都会被自动归类到一个未命名模块,即不使用模块化的话,类其实也属于一个模块。未命名模块可以读取其它命名模块,但是我新建一个Test类,然后在该类中使用上面的main_modul模块中的Main类,然后使用-p选项指定使用的模块所在路径进行编译的话会出错,暂时不知道什么原因。所以现在在未命名模块中不能使用命名模块,只能是依旧按照类路径来使用模块文件夹中的Main类,如果想要使用命名模块的话,可以将使用的类设置为一个命名模块:

  比如现在的main_module模块中要使用Test类,那么我们可以先将Test类设置成一个命名模块func_module,方法与上面所说的将Main设置成main_module模块是一样的,但是模块描述文件module-info.java需要设置为以下内容:

  然后main_module要使用func_module模块的话,我们需要修改main_module模块的模块配置文件module-info.java和Main类,如下所示,并且要将func_module模块放置与main_module模块同样的目录下,这里我们新建一个mods目录来放置所有的模块,然后重新编译和执行main_module模块来使用Test,需要注意的是这里要先编译模块配置文件以声明依赖的模块,然后再编译类文件:

3、

  在编译的时候使用--module-source-path可以指定模块的原始码路径,使用它可以一次性编译整个模块而不用分别对模块中的源文件和模块配置文件进行编译,方法是将模块代码文件和模块配置文件放到一个与当前模块名称相同的目录中,然后将这个模块目录再放到一个目录中,比如下面为将Test的模块代码文件和模块配置文件放到了func_module中,然后又将func_module放到了src中,使用“javac -d 目标文件夹 ...” 编译的时候会自动在目标文件夹下生成模块,如下为将模块生成到mod目录下:

   使用--module-source-path还可以一次性对多个模块进行编译,方法是将模块代码文件和模块配置文件放到一个与当前模块名称相同的目录中,然后将这个模块目录放到一个目录中,比如下面为将Main的模块代码文件和配置文件放到了main_module中,然后将main_module放到了src中,因为main_module中使用了func_module,所以还要将func_module放到src中,使用“javac -d 目标文件夹 ...” 编译的时候会自动在目标文件夹下生成各个模块,如下为将模块生成到mods目录下:

 


4、  

  使用NetBeans创建的项目可以通过添加Java Module Info文件(即module-info.java文件)来让它支持模块管理,建立的module-info.java中会使用项目名称来作为模块名称。暂时发现一个项目下只能添加一个Java Module Info文件即一个模块,目前不知道是不是NetBeans的硬性规定。

5、

  java.base模块下包含java.lang,java.io,java.math等核心java se包,java.base模块默认是exports的,而且其它模块默认隐含了requires java.base,所以它可以被其它模块直接使用。java.util.logging不是在java.base下,因为其在JDK9中被划分至java.logging包模块,所以如果项目使用模块化的话,模块配置文件必须reqquires java.logging。

  在类路径下被发现的类,都会被归类为未命名模块,在模块路径下发现的类,都属于这个命名模块。如果不打算模块化,程序中使用的每个类都是基于类路径,也就是都在未命名模块中。在JDK9中,java.se.ee模块虽然包含在Java SE中,但其实际上是与Java EE相关的API,JVM默认不会加载这个模块,如果会使用(或者使用的JAR中会使用)到javax.xml..bind*、javax.rmi等java.se.ee下的包的话,编译和执行的时候还需要加上--add-modules java.se.ee。

  如果一个类使用模块化的话,那么就不能直接使用类路径的类,因为显示模块不能依赖在未命名模块中。所以在模块化的类中如果需要使用一个不是模块化的JAR的话,可以将这个JAR放到模块路径中,使该JAR成为自动模块,自动模块也是命名模块的一种,其名称产生的规则如下所示,这样我们就可以requires该自动模块。

  一个包不能同时出现在被requires的两个模块中——这句话还不太理解,不知道意思是不是这样:在同一个项目中,一个模块被多个模块使用的话,这个模块只需被其它模块requires一次即可。

  如果要A模块中想要对B模块使用深层反射的话,B模块应该是open的,或者A模块中opens指定的包,如下所示。java.base模块不是open的,所以不能对其做深层反射。open了的模块称为开放模块,否则称为一般模块。

open module B{
    exports packt; //本模块下packt包可以被其它模块使用
}
module A {
    requires B; //因为要使用B模块,所以声明本模块依赖B模块
    opens packt;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值