Новые ключевые слова в Java 9

Одной из самых больших функций Java 9 будет модульная система, определенная Project Jigsaw. Читая слайды из проекта Jigsaw: Under the Hood на JavaOne 2015, я заметил следующий исходный код:

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

Что мне здесь интересно, так это то, что файл заканчивается .java и, кажется, использует два новых ключевых слова: module, а также exports, Какие другие ключевые слова будут введены в Java 9? Как обратная совместимость будет решаться (то есть функции или переменные module)?

4 ответа

Решение

Ключевые слова, добавленные для объявлений модулей в Java 9, обобщены в §3.9 Спецификации языка Java, Java SE 9 Edition:

Еще десять последовательностей символов являются ограниченными ключевыми словами: open, module, requires, transitive, exports, opens, to, uses, provides, а также with, Эти символьные последовательности маркируются как ключевые слова исключительно там, где они появляются как терминалы в продуктах ModuleDeclaration и ModuleDirective (§7.7). Они повсеместно маркируются как идентификаторы для совместимости с программами, написанными до Java SE 9. Существует одно исключение: непосредственно справа от последовательности символов требуется в модуле ModuleDirective, транзитивная последовательность символов маркируется как ключевое слово, если только за ним следует разделитель, и в этом случае он маркируется как идентификатор.

Если у вас есть метод с именем moduleили любое другое ключевое слово, перечисленное здесь, он продолжит компиляцию.

(view а также permits были ключевыми словами в раннем Jigsaw-прототипе, но они давно были упрощены.)

Вероятно, это не полный список, и, насколько мне известно, ничего из этого не было завершено, но я нашел несколько.

У нас также есть module, exports, provides, uses, with, to, а также requires; объяснил здесь:

Модульная система может идентифицировать использование сервисов путем сканирования файлов классов в артефактах модулей на предмет вызова методов ServiceLoader::load, но это будет как медленно, так и ненадежно. То, что модуль использует конкретную службу, является фундаментальным аспектом определения этого модуля, поэтому для эффективности и ясности мы выражаем это в объявлении модуля с помощью использования:

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 сегодня. Однако то, что модуль предоставляет реализацию конкретной службы, является в равной степени фундаментальным, поэтому мы выражаем это в объявлении модуля с предложением обеспечивает:

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

Также view а также permits:

В больших программных системах часто бывает полезно определить несколько представлений одного и того же модуля. Одно представление может быть объявлено для общего использования любым другим модулем, а другое обеспечивает доступ к внутренним интерфейсам, предназначенным только для использования выбранным набором тесно связанных модулей.

Например, с помощью JNDI мы хотим, чтобы com.sun.jndi.toolkit.url был видимым только для модулей коснания и kerberos, как указано в объявлении модуля.

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

}

Таким образом, у нас больше гибкости в определении границ модулей.

Я также слышал упоминание о optional,

*

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;

     }
}

* Проверьте это может вам помочь.

module- это новое ключевое слово, введенное для определения взаимозависимостей между пакетами. Зачем нам нужны модули? Потому что раньше

  1. Инкапсуляция не была безупречной. С помощью рефлексии и с помощью аналогичных методов мы могли получить доступ даже к частному полю.
  2. Все классы во всех банках были общедоступны.
  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;
}

Другими используемыми атрибутами являются "экспорт" и "требуется" для создания взаимозависимости (только транзитивная зависимость), "предоставляет" и "с" для предоставления интерфейса и упоминания реализации. Так что, возможно, это сильная инкапсуляция, поэтому java 9 более склонна к лучшей объектно-ориентированной функции.

Для обратной совместимости часть вопроса.

Я думаю, что JAVA9/ Project Jigsaw - это смена парадигмы в технологии Java. так что java9 не будет обратно совместимым, но вы можете легко преобразовать свою немодулярную зависимость с помощью модульной версии той же библиотеки. Концепция "Нет боли, нет выгоды" будет работать здесь. Каждый должен обновить / трансформироваться, чтобы воспользоваться преимуществами новой модульной Java. Разработчик IDE, разработчик плагинов, Build System и, конечно, разработчик Java уровня groud уровня должны понимать новые системы Java.

JAVA9 выступает за чистую зависимость. это также обеспечивает совершенно новый способ защиты вашего кода с помощью частных модулей. даже отражение не может получить доступ к модулям, не выставленным владельцем библиотеки /API.

Существует два подхода к использованию немодульных LIB/API.

  1. Нисходящий подход
  2. Подход снизу вверх (много боли здесь для реализации)

Второй подход - создать очень чистую иерархию зависимостей модуля.

Другие вопросы по тегам