Java 9 中的新关键字

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 9 中还将引入哪些其他关键字?如何处理向后兼容性(即命名的函数或变量)?.javamoduleexportsmodule


答案 1

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

另外十个字符序列是受限制的关键字:、、、和。这些字符序列仅作为终端出现在 ModuleDeclaration 和 ModuleDirective 作品 (§7.7) 中作为终端出现的地方被标记为关键字。它们在其他任何地方都被标记为标识符,以便与Java SE 9之前编写的程序兼容。有一个例外:在 ModuleDirective 生产中,字符序列传递的右侧立即被标记化为关键字,除非它后面跟着一个分隔符,在这种情况下,它被标记为标识符。openmodulerequirestransitiveexportsopenstousesprovideswith

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

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


答案 2

这可能不是一个完整的列表,据我所知,这些都没有最终确定,但我找到了一些。

我们还有 、 、 、 、 和 ;解释如下moduleexportsprovidesuseswithtorequires

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

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/services 资源条目来识别服务提供者,就像今天的 ServiceLoader 类一样。但是,模块提供特定服务的实现同样重要,因此我们在模块的声明中用 offers 子句来表示这一点:

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 仅对 cosnameing 和 kerberos 模块可见,如模块声明中所指定的那样。

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

}

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

我也听说过.optional