专栏首页JAVA同学会JAVA9模块化详解(一)——模块化的定义

JAVA9模块化详解(一)——模块化的定义

JAVA9模块化详解

前言

java9已经出来有一段时间了,今天向大家介绍一下java9的一个重要特性——模块化。模块化系统的主要目的如下:

  • 更可靠的配置,通过制定明确的类的依赖关系代替以前那种易错的类路径(class-path)加载机制。
  • 强大的封装,允许一个组件声明它的公有类型(public)中,哪些可以被其他组件访问,哪些不可以。

这些特性将有益于应用的开发者、类库的开发者和java se平台直接的或者间接地实现者。它可以使系统更加健壮,并且可以提高他们的性能。

一、定义模块化

  为了提高可靠的配置性和强大的封装性,我们将模块化看作是java程序组件的一个基本的新特性,这样它对开发者和可支持的工具更加友好。一个模块是一个被命名的,代码和数据的自描述的集合。它的代码有一系列包含类型的包组成,例如:java的类和接口。它的数据包括资源文件(resources)和一些其他的静态信息。

1.1 模块的声明

一个模块的自描述表现在它的模块声明中,它是java程序语言中的一个新的结构,最简单的可能的模块声明仅仅是指定模块的名字

module com.foo.bar { }

  一个或更多个requires项可以被添加到其中,它通过名字声明了这个模块依赖的一些其他模块,在编译期和运行期都依赖的。

module com.foo.bar {
    requires org.baz.qux;
}

  最后,exports项可以被添加,它可以仅仅使指定包(package)中的公共类型可以被其他的模块使用。

module com.foo.bar {
    requires org.baz.qux;
    exports com.foo.bar.alpha;
    exports com.foo.bar.beta;
}

如果一个模块的声明中没有exports项,则它根本不向其他模块输出任何的类型。

  按照约定,模块声明的源代码被放在了模块源文件结构的根目录,文件的名字叫module-info.java。例如:模块com.foo.bar包含的文件如下:

  按照约定,模块声明被编译到module-info.class文件中,并输出到类文件的输出目录。

  模块的名字,像包的名字一样,必须不能重复。命名模块的推荐方式是使用反转域名的方式,它长期被推荐使用到包的命名。模块的名字经常是它的输出包的前缀,但是这个关系也不是强制的。模块的声明既不包括版本号,也不包括它依赖模块的版本号。这是有意这样的:解决版本选择问题不是模块化系统的目的,这个问题最好留个构建工具和容器应用。

  模块声明是java程序语言的一部分,而不是他们自己的一个语言或标记,有几个原因:其中最重要的一个原因是模块的信息在编译期和运行期都可用,确保在编译期和运行期以相同的方式运行。这样可以防止很多种错误,至少在编译期提前报告,并且可以更早的诊断和修复。

  在一个源文件中表达模块声明,它可以连同模块中的其他文件一起编译,编译成的类文件可以被java虚拟机消费。这种方式对于开发者来说非常熟悉,IDE和构建工具也不难支持。

1.2 模块的零件

存在的工具已经可以创建,处理,消费jar文件,为了采用和迁移简单,我们定义了模块jar文件。一个模块jar文件非常像一个普通的jar文件,除了在根目录包含了一个module-info.class。例如上面的com.foo.bar模块jar文件包含以下的内容:

  模块jar文件可以作为模块使用,在这种情况下,module-info.class包含了模块的声明它可以放在普通的类路径下,这种情况下,module-info.class将被忽略。模块jar文件允许类库的维护者装载一个单一的零件,它可以作为一个模块工作(在java9以后)也可以作为一个普通的jar文件工作。我们希望java9的实践者提升jar工具,使得它更容易的生成模块jar文件。

  为了模块化java平台的相关实现,我们介绍了一个新的零件格式,它超越了jar文件,容纳了本地代码、配置文件、和其他的不能自适应的数据类型。这种格式促使模块声明表达式的另外一个优点,把它们编译到class文件中,这个class文件是独立的,这种新的格式,暂时命名为“JMOD”,它被标准化是一个公开的议题。

1.3 模块描述

编译模块声明到一个类文件的优点是这个类文件有了一个精确定义和可扩展的格式,我们认为module-info.class,它包含了代码级别的编译模式,里边插入的其他变量在初始化时也会被编译。

   一个IDE或者打包工具可以插入一些包含标记信息的变量,例如:模块的版本、标题、描述、和许可等。这些信息在编译期和运行期都会被模块系统映射成可使用的信息。它也可以被下游工具构建时使用。指定的变量的集合将被标准化,但是其他的工具和框架也可以定义额外的需要的变量。没有标准化的变量在模块系统中是没有效果的。

1.4 平台模块

java9将使用模块化系统将平台分割成若干个子模块。java9平台的实现者可以包含其中的所有模块,也可以是其中的一些。

  模块系统中明确知道的模块是基础模块,它被命名为java.base。基础模块定义和输出所有平台的核心包,包括模块系统本身:

module java.base {
    exports java.io;
    exports java.lang;
    exports java.lang.annotation;
    exports java.lang.invoke;
    exports java.lang.module;
    exports java.lang.ref;
    exports java.lang.reflect;
    exports java.math;
    exports java.net;
    ...
}

  基础模块总是实时的,其他的每一个模块都隐式的依赖基础模块。其他的平台模块将通过“java.”的前缀分享,例如:java.sql的数据库连接,java.xml处理xml文件,java.log处理日志,java9没有定义的,将会通过“jdk.”的前缀分享出来。

  至此,java9的模块化先定义到这里,翻译的不好,大家见谅,稍后会继续介绍java模块化的使用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Boot 2.0 系列(一):快速开始

    Spring Boot可以使我们轻松地创建独立的、生产级的基于Spring的应用程序,由于整合了一些对Spring和第三方库的配置,我们可以快速开始一个应用程序...

    Vi的技术博客
  • Java 基础系列(一):基础数据类型

    今天我们来聊一下Java这门语言的数据类型,众所周知,Java是一种强类型语言。在Java中,一共有8种基本类型,其中4种整形,2种浮点类型,1种用于表示Uni...

    Vi的技术博客
  • Java基础系列(二):运算符

    计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:

    Vi的技术博客
  • Kotlin入门(20)几种常见的对话框

    手机上的App极大地方便了人们的生活,很多业务只需用户拇指一点即可轻松办理,然而这也带来了一定的风险,因为有时候用户并非真的想这么做,只是不小心点了一下而已,如...

    用户4464237
  • 异常、堆内存溢出、OOM的几种情况

    【情况一】:    java.lang.OutOfMemoryError: Java heap space:这种是java堆内存不够,一个原因是真不够,另一个...

    业余草
  • Java基础系列(五):数组

    在Java中,有一种数据结构叫做数组,它用来存储同一类型的值的集合。通过一个整型下标可以访问数组中的每一个值。例如,如果a是一个整型数组,那么a[i]就是数组中...

    Vi的技术博客
  • Java基础专题(三):字符串

    从概念上来讲,Java字符串就是Unicode字符序列。例如,"Java\u2122" 由5个Unicode字符J,a,v,a,和 ™。Java没有内置的字符串...

    Vi的技术博客
  • Kotlin入门(21)活动页面的跳转处理

    Activity的活动页面跳转是App最常用的功能之一,在前几章的demo源码中便多次见到了,常常是点击界面上的某个按钮,然后跳转到与之对应的下一个页面。对于A...

    用户4464237
  • Java基础系列(四):控制流程

    和其他程序设计语言一样,Java使用条件语句和循环结构确定控制流程,在介绍这些条件语句和循环结构之前,我们先来了解一下块作用域这个概念。

    Vi的技术博客
  • Java基础系列(十二):继承

    Java中有一个非常重要的概念:继承。利用继承,我们可以通过一个已经存在的类构造一个新的类,继承已经存在的类就是服用这些类的方法和数据域,并且在原本类的基础上可...

    Vi的技术博客

扫码关注云+社区

领取腾讯云代金券