Java 9 中的新关键字

New Keywords in Java 9

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

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

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

这可能不是完整的列表,据我所知,其中 none 已经完成,但我找到了一些。

我们还有 moduleexportsprovidesuseswithtorequires ;解释 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;
}

还有 viewpermits:

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.

我也听说过 optional

Java9中为模块声明添加的关键字总结在 Java 语言规范的 §3.9,Java SE 9 版本

A further ten character sequences are restricted keywords: open, module, requires, transitive, exports, opens, to, uses, provides, and with. These character sequences are tokenized as keywords solely where they appear as terminals in the ModuleDeclaration and ModuleDirective productions (§7.7). They are tokenized as identifiers everywhere else, for compatibility with programs written prior to Java SE 9. There is one exception: immediately to the right of the character sequence requires in the ModuleDirective production, the character sequence transitive is tokenized as a keyword unless it is followed by a separator, in which case it is tokenized as an identifier.

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

(viewpermits 是早期 Jigsaw 原型中的关键字,但是 他们很久以前就被简化了。)

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

我认为 JAVA9/project jigsaw 是 Java 技术的范式转变。 这样 java9 将不会向后兼容,但您可以使用同一库的模块化版本轻松转换非模块化依赖项。 "No-Pain , No-Gain" 的概念将在这里起作用。 每个人都必须 upgrade/transform 才能利用新的模块化 java。 IDE 开发人员、插件开发人员、构建系统,当然还有底层 java 开发人员需要了解新的 java 系统。

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

有两种使用非模块化的方法LIB/APIs。

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

第二种方法创建了一个非常干净的模块依赖层次结构。

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

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

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

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

    因此,出于上述所有原因,我们需要一种机制让 JVM 在 运行 时知道这一点。为了实现模块,你需要定义module-info.javain that package

        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 更倾向于更好的面向对象的特性。

*

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;

     }
}

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