Java中的新关键字9

时间:2016-03-31 00:37:37

标签: java syntax java-9 jigsaw

Java 9的最大功能之一将是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。 Java 9中将引入哪些其他关键字?如何处理向后兼容性(即名为module)的函数或变量?

5 个答案:

答案 0 :(得分:65)

在Java 9中为模块声明添加的关键字总结如下 Java Language Specification, Java SE 9 Edition中的§3.9:

  

另外十个字符序列是受限制的关键字:open,     modulerequirestransitiveexportsopenstouses,     provideswith。这些字符序列被标记为     关键字仅在ModuleDeclaration中显示为终端的位置     和ModuleDirective制作(第7.7节)。它们被标记为     其他地方的标识符,与编写的程序兼容     在Java SE 9之前。有一个例外:紧靠右侧     在ModuleDirective制作中需要字符序列,     字符序列传递被标记为关键字,除非它     后跟一个分隔符,在这种情况下它被标记为一个     标识符

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

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

答案 1 :(得分:5)

这可能不是一个完整的清单,根据我的知识,这些都没有最终确定,但我发现了一些。

我们还有moduleexportsprovidesuseswithtorequires;解释here

  

模块系统可以通过扫描模块工件中的类文件来识别ServiceLoader :: load方法的调用来识别服务的使用,但这既缓慢又不可靠。模块使用特定服务是该模块定义的一个基本方面,因此为了效率和清晰度,我们在模块的声明中用uses子句表示:

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;
}
     

模块系统可以通过扫描META-INF /服务资源条目的模块工件来识别服务提供者,就像ServiceLoader类今天所做的那样。但是,模块提供特定服务的实现同样是基础,因此我们在模块的声明中用provide子句表示:

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

  

在大型软件系统中,定义同一模块的多个视图通常很有用。一个视图可以声明为任何其他模块的一般用途,而另一个视图提供对内部接口的访问,这些接口仅供一组紧密相关的模块使用。

     

例如,对于JNDI,我们希望com.sun.jndi.toolkit.url仅对cosnaming和kerberos模块可见,如模块声明中所指定。

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

}

     

通过这种方式,我们可以更灵活地定义模块边界。

我也听说过optional

答案 2 :(得分: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;

     }
}

* 检查一下可能对您有帮助。

答案 3 :(得分:-1)

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

  1. 封装并不完美无暇。借助反思和类似技术,我们甚至可以访问私人领域。
  2. 所有罐子里的所有课程都可以公开访问。
  3. 如果类加载器没有获得类,则必须查看很多区域并加载大量相关文件,如果找不到类,则会在运行时抛出NoClassDefFoundErrors。 / p>

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

        module com.exporter{
    
         exports com.a;
         provides com.b.M;
          with com.b.MImpl; }
    
  4. 在其他一些包中,

    module com.consume {
        requires com.a;
    }
    

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

答案 4 :(得分:-4)

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

我认为JAVA9 /项目拼图是Java技术的范例转换。 因此java9不会向后兼容,但您可以使用同一库的模块化版本轻松转换非模块化依赖项。 “没有痛苦,没有收获”的概念将在这里发挥作用。 每个人都必须升级/转换以利用新的模块化Java。 IDE开发人员,插件开发人员,构建系统以及当然不熟悉Java系统的人员。

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

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

  1. 自上而下的方法
  2. 自下而上的方法(这里实施很多痛苦)
  3. 第二种方法是一个非常干净的模块依赖层次结构。