42

Java 9 最大的特性之一将是由 Project Jigsaw 定义的模块系统。在阅读Project Jigsaw: Under the Hood at JavaOne 2015 的幻灯片时,我注意到以下源代码:

// src/java.sql/module-info.java
module java.sql {
   exports java.sql;
   exports javax.sql;
   exports javax.transaction.xa;
}

对我来说有趣的是该文件以.java并且似乎使用了两个新关键字结尾:moduleexports. Java 9 中还会引入哪些其他关键字?如何处理向后兼容性(即名为 的函数或变量module)?

4

5 回答 5

67

Java 9 中为模块声明添加的关键字总结在Java 语言规范 Java SE 9 版的第 3.9 节中:

另外十个字符序列是受限关键字:open, module, requires, transitive, exports, opens, to, uses, provides, 和with. 这些字符序列仅在它们在 ModuleDeclaration 和 ModuleDirective 产品(第 7.7 节)中作为终端出现时才被标记为关键字。它们在其他任何地方都被标记为标识符,以便与 Java SE 9 之前编写的程序兼容。有一个例外:在 ModuleDirective 产生式中紧邻字符序列要求的右侧,字符序列传递被标记为关键字,除非它是后跟一个分隔符,在这种情况下,它被标记为标识符。

如果您目前有一个名为 的方法module,或此处列出的任何其他关键字,它将继续编译。

view并且permits是早期 Jigsaw 原型中的关键字,但它们在很久以前就被简化了。)

于 2016-03-31T01:38:19.107 回答
6

This is likely not a complete list, and none of this has been finalized to the best of my knowledge, but I found a few.

We also have module, exports, provides, uses, with, to, and requires; explained here:

The module system could identify uses of services by scanning the class files in module artifacts for invocations of the ServiceLoader::load methods, but that would be both slow and unreliable. That a module uses a particular service is a fundamental aspect of that module’s definition, so for both efficiency and clarity we express that in the module’s declaration with a uses clause:

module java.sql {
    requires public java.logging;
    requires public java.xml;
    exports java.sql;
    exports javax.sql;
    exports javax.transaction.xa;
    uses java.sql.Driver;
}

The module system could identify service providers by scanning module artifacts for META-INF/services resource entries, as the ServiceLoader class does today. That a module provides an implementation of a particular service is equally fundamental, however, so we express that in the module’s declaration with a provides clause:

module com.mysql.jdbc {
    requires java.sql;
    requires org.slf4j;
    exports com.mysql.jdbc;
    provides java.sql.Driver with com.mysql.jdbc.Driver;
}

...

module java.base {
    ...
    exports sun.reflect to
        java.corba,
        java.logging,
        java.sql,
        java.sql.rowset,
        jdk.scripting.nashorn;
}

Also view and permits:

In large software systems it is often useful to define multiple views of the same module. One view can be declared for general use by any other module, while another provides access to internal interfaces intended only for use by a select set of closely-related modules.

For example with JNDI we want that com.sun.jndi.toolkit.url be visible only for cosnaming and kerberos modules, as specified in the module declaration.

view jdk.jndi.internal {
    exports com.sun.jndi.toolkit.url.*;
    exports sun.net.dns.*;
    permits jdk.cosnaming;
    permits jdk.kerberos;

}

This way we have more flexibility to define module boundaries.

I've also heard mention of optional.

于 2016-03-31T00:49:12.600 回答
0

*

module mainModule @ 2.0 {

    requires A @ >= 3.0 ;   // Use version 3 or above  

    //scope:compilation,execution,reflection
    requires B for compilation optional execution;

    requires optional service S1; 
    requires static E; // need at compile time but optional at runtime 

    // let mmm requires mainModule then S2 will automatically be there for mmm
    requires transitive S2; 

    provides MI @ 2.0; 
    provides service MS with C; // provide service with impelemented class C

    exports  pack;  
    exports  pack.abc to D; //qulified export

    permits  MF;
    class    MMain;

    /*
     syntax for creating view
     view ModuleName {
         {ProvidesDir|ExportsDir|PermitsDir|EntrypointDir}
     }
   */

    view N {

        provides service NS with AD;
        exports  MA;
        permits  MB;
        class    Main;

     }
}

* 看看它可能对你有帮助。

于 2020-04-14T08:39:56.000 回答
-1

module是引入的一个关键字,用于定义包之间的相互依赖关系。为什么我们需要模块?因为早些时候

  1. 封装并不完美。在反射和类似技术的帮助下,我们甚至可以访问私有字段。

  2. 所有 jar 中的所有类都可以公开访问。

  3. 如果 Classloader 没有得到类,它必须查看很多区域并加载很多相关文件,即使在此之后如果找不到 Class,它也会在运行时抛出 NoClassDefFoundErrors。

    因此,出于上述所有原因,我们需要一种机制让 JVM 在运行时知道这一点。为了实现模块,您需要定义module-info.java. 在那个包裹里

        module com.exporter{
    
         exports com.a;
         provides com.b.M;
          with com.b.MImpl; }
    

在其他一些包中,

module com.consume {
    requires com.a;
}

使用的其他属性是“ exports ”和“ requires ”用于建立相互依赖(仅传递依赖),“ provides ”和“ with ”用于公开接口和提及实现。所以它可能是一个强大的封装,这就是为什么 java 9 更倾向于更好的面向对象特性。

于 2017-07-19T14:23:05.510 回答
-5

对于问题的向后兼容性部分。

我认为 JAVA9/project jigsaw 是 Java 技术的一种范式转变。这样java9就不会向后兼容,但是你可以很容易地用同一个库的模块化版本转换你的非模块化依赖。“No-Pain , No-Gain”的概念将在这里发挥作用。每个人都必须升级/改造以利用新的模块化 java。IDE 开发人员、插件开发人员、构建系统,当然还有底层 Java 开发人员需要了解新的 Java 系统。

JAVA9 提倡干净的依赖。它还提供了一种全新的方式来通过私有模块保护您的代码。甚至反射也无法访问库/API 所有者未公开的模块。

有两种方法可以使用非模块化 LIB/API。

  1. 自上而下的方法
  2. 自下而上的方法(实施起来很痛苦)

第二种方法使模块依赖层次结构非常干净。

于 2016-05-13T12:50:06.373 回答