栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java模块化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java模块化

模块化

前言Moudle

模块的申明模块访问控制

exportsopens 声明依赖

requires 服务消费

usesprovides

前言

模块化(Module),项目名字叫做Jigsaw(拉锯),拉了多年的锯,终于把java锯成了一个个模块。到jdk1.8,jre的rt.jar已经有65M了,运行一个HelloWorld也需要近百兆的JRE环境。还有就是jar hell。就是类路径重复造成的:

    Libary中jar包改名了,新老jar包一起,不容易识别。jar包间存在传递依赖有些类在jar包间复制使用

模块化可以将jar声明为模块,它将在其自己的隔离类加载器中运行,该类加载器以OSGI方式从其他类似的模块类加载器读取类文件。这将允许同一版本的Jar的多个版本共存。

Moudle 模块的申明

模块名只要是合法java标识符就可以,和同名的类名、包名、变量名不冲突。

//以包路径命名
module jdk.compiler1 {}
//一个名叫module的模块
module module{}
//var不与int var冲突
module var{}
模块访问控制

导出(exports)和开放(opens)语句用于控制对模块代码的访问。

exports

表示允许在编译时和运行时访问指定包的public成员。

    如果一个模块声明中的多个exports指令指定了相同的包名,则这是一个编译时错误。指定的包exports未由与当前模块关联的编译单元声明,则为编译时错误
exports willem.com.sun.source.tree;
//将javac.api导出给jdk.javadoc和jdk.jshell模块
exports willem.com.sun.tools.javac.api to
        jdk.javadoc,
        jdk.jshell;
opens

opens用于声明该模块的指定包在运行时(而不是编译期)允许使用反射访问。

module java.house {
    // 所有模块都可以在运行时使用反射访问com.xhx.house模块
    opens com.xhx.house;
    //com.xhx.user可以在运行时使用反射访问com.xhx.house模块
    opens com.xhx.house to com.xhx.user;;
}

open的作用是表示该模块下的所有的包在runtime都允许深度反射(包括public及private类型) 但是编译时期不可以。但是编译时期,仅仅允许该module中声明过exports的包可以访问,如果没有exports则该包的类在编译时期不可读。

open java.house {
    //里面不能再使用opens了,因为整个包都已经open了,可以用exports
}
声明依赖 requires

指定当前模块所依赖的模块。requires transitive java.compiler和requires java.compiler都是申明了依赖,但前一个具有传递性,如果有模块依赖
jdk.compiler1,但没有直接申明依赖java.compiler,它仍然可以读取java.compiler模块。如果没有transitive而且也没显示声明依赖java.compiler就无法读取此模块。

module jdk.compiler1 {
	requires transitive java.compiler;
}
服务消费 uses

uses ,当前模块中的代码可以通过java.util.ServiceLoader发现和加载此接口的实现。如果uses指令指定枚举类,编译报错。该服务可以在当前模块或另一个模块中声明。如果服务未在当前模块中声明,则该服务必须可被当前模块中的代码访问,否则编译错误。

module jdk.compiler1 {
//javac编译器使用它提供平台服务。
	uses willem.com.sun.tools.javac.platform.PlatformProvider;
}
provides

该服务可以在当前模块或另一个模块中声明。如果服务未在当前模块中声明,则该服务必须可被当前模块中的代码访问,否则发生编译错误。每个服务提供者必须是顶级或静态的公共类或接口,否则会发生编译时错误。

//结合上面的uses,模块内部自己提供服务,自己使用,也可以一个模块提供,一个使用
module jdk.compiler1 {
	provides willem.com.sun.tools.javac.platform.PlatformProvider with
            willem.com.sun.tools.javac.platform.JDKPlatformProvider;
 }

这是JDKPlatformProvider中提供平台支持JDK版本的核心代码。如果没有module-info.java中的服务提供发现机制,编译器就无法指定对应的jdk版本

static {
        SUPPORTED_JAVA_PLATFORM_VERSIONS = new TreeSet<>(NUMERICAL_COMPARATOR);
        Path ctSymFile = findCtSym();
        if (Files.exists(ctSymFile)) {
            try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, (ClassLoader)null);
                 DirectoryStream dir =
                         Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) {
                for (Path section : dir) {
                    if (section.getFileName().toString().contains("-"))
                        continue;
                    for (char ver : section.getFileName().toString().toCharArray()) {
                        String verString = Character.toString(ver);
                        Target t = Target.lookup("" + Integer.parseInt(verString, Character.MAX_RADIX));

                        if (t != null) {
                            SUPPORTED_JAVA_PLATFORM_VERSIONS.add(targetNumericVersion(t));
                        }
                    }
                }
            } catch (IOException | ProviderNotFoundException ex) {
            }
        }
    }

明明在jdk17中却不支持17,就是平台服务未被发现

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/749823.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号