Разное

Модуль в java: Общие сведения о модулях Java

Class Module Именованные модули создаются виртуальной машиной Java, когда для создания слоя определен граф.

java.lang.Object

java.lang.Module

Все реализованные интерфейсы:
AnnotatedElement
public final class Module extends Object implements AnnotatedElement

Представляет модуль времени выполнения с named или без имени.

Именованные модули имеют name и создаются виртуальной машиной Java, когда граф модулей определяется виртуальной машиной Java для создания уровня модулей .

Безымянный модуль не имеет имени. ClassLoader существует безымянный модуль , полученный вызовом его метода getUnnamedModule . Все типы, которые не находятся в именованном модуле, являются членами безымянного модуля определяющего их загрузчика классов.

Имена пакетов, которые являются параметрами или возвращаются методами, определенными в этом классе, являются полными именами пакетов, как определено в разделе 6. 5.3 .Спецификация языка Java, например, "java.lang" .

Если не указано иное, передача null аргумента методу в этом классе вызывает NullPointerException .

SeeСпецификация языка Java:
7.7 Декларации модулей
Since:
9
See Also:
  • Class.getModule()

Method Summary

Модификатор и типMethodDescription
ModuleaddExports(String pn, Module other)

Если модуль вызывающей стороны является этим модулем,то обновите этот модуль,чтобы экспортировать данный пакет в данный модуль.

ModuleaddOpens(String pn, Module other)

Если этот модуль открыл пакет хотя бы для вызывающего модуля, обновите этот модуль, чтобы открыть пакет для данного модуля.

ModuleaddReads(Module other)

Если модуль вызывающей стороны является этим модулем,то обновить этот модуль для чтения данного модуля.

ModuleaddUses(Class<?> service)

Если модуль вызывающей стороны является этим модулем,то обновите этот модуль,чтобы добавить зависимость услуги от заданного типа услуги.

booleancanRead(Module other)

Указывает,читает ли данный модуль заданный модуль.

booleancanUse(Class<?> service)

Указывает,имеет ли данный модуль зависимость от данного типа сервиса.

<T extends Annotation>
T
getAnnotation(Class<T> annotationClass)

Возвращает аннотацию этого элемента для указанного типа, если такая аннотация присутствует , иначе null.

Annotation[]getAnnotations()

Возвращает аннотации, присутствующие в этом элементе.

ClassLoader
getClassLoader()

Возвращает ClassLoader для этого модуля.

Annotation[]getDeclaredAnnotations()

Возвращает аннотации, которые непосредственно присутствуют в этом элементе.

ModuleDescriptorgetDescriptor()

Возвращает дескриптор модуля для этого модуля или null , если этот модуль является безымянным модулем.

ModuleLayergetLayer()

Возвращает уровень модуля, содержащий этот модуль, или null , если этот модуль не находится на уровне модуля.

StringgetName()

Возвращает имя модуля или значение null , если этот модуль является безымянным модулем.

Set<String>getPackages()

Возвращает набор имен пакетов для пакетов в этом модуле.

InputStreamgetResourceAsStream(String name)

Возвращает входной поток для чтения ресурса в этом модуле.

booleanisExported(String pn)

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

booleanisExported(String pn, Module other)

Возвращает true если этот модуль экспортирует данный пакет по крайней мере в данный модуль.

booleanisNamed()

Возвращает true если этот модуль является именованным модулем.

booleanisOpen(String pn)

Возвращает true , если этот модуль безоговорочно открыл пакет.

booleanisOpen(String pn, Module other)

Возвращает true если этот модуль открыл пакет по крайней мере для данного модуля.

StringtoString()

Возвращает строковое представление этого модуля.

Методы, объявленные в классе java.lang. Объект

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Методы, объявленные в интерфейсе java.

lang.reflect. AnnotatedElement

getAnnotationsByType, getDeclaredAnnotation, getDeclaredAnnotationsByType, isAnnotationPresent

Method Details

isNamed

public boolean isNamed()

Возвращает true если этот модуль является именованным модулем.

Returns:
true если это именованный модуль
SeeСпецификация языка Java:
7.7.5 Неименованные модули
See Also:
  • ClassLoader.getUnnamedModule()

getName

public String getName()

Возвращает имя модуля или значение null , если этот модуль является безымянным модулем.

Returns:
Название модуля

getClassLoader

public ClassLoader getClassLoader()

Возвращает ClassLoader для этого модуля.

Если есть диспетчер безопасности, то его метод checkPermission при первом вызове с RuntimePermission("getClassLoader") проверяет, разрешен ли вызывающему объекту доступ к загрузчику классов.

Returns:
Загрузчик классов для этого модуля
Throws:
SecurityException — если отказано менеджером безопасности

getDescriptor

public ModuleDescriptor getDescriptor()

Возвращает дескриптор модуля для этого модуля или null , если этот модуль является безымянным модулем.

Returns:
Дескриптор модуля для этого модуля

getLayer

public ModuleLayer getLayer()

Возвращает уровень модуля, содержащий этот модуль, или null , если этот модуль не находится на уровне модуля. Уровень модуля содержит именованные модули, и поэтому этот метод всегда возвращает null при вызове безымянного модуля.

Динамические модули — это именованные модули, которые создаются во время выполнения. Динамический модуль может находиться или не находиться на модульном уровне.

Returns:
Слой модуля,который содержит этот модуль
See Also:
  • Proxy

canRead

public boolean canRead(Module other)

Указывает, читает ли этот модуль данный модуль. Этот метод возвращает true если вызывается для проверки, читает ли этот модуль сам себя. Он также возвращает true если вызывается для безымянного модуля (поскольку безымянные модули читают все модули).

Parameters:
other
— Другой модуль
Returns:
true если этот модуль читает other
See Also:
  • addReads(Module)

addReads

public Module addReads(Module other)

Если модуль вызывающего абонента является этим модулем, обновите этот модуль, чтобы прочитать данный модуль. Этот метод не работает, если other является этим модулем (все модули читают сами себя), этот модуль является безымянным модулем (поскольку безымянные модули читают все модули), или этот модуль уже читает other .

Implementation Note:
Read краев добавлены этот метод слаб и не мешает other от того GC’ed , когда этот модуль сильно достижимый.
Parameters:
other
— Другой модуль
Returns:
this module
Throws:
IllegalCallerException — если это именованный модуль, а модуль вызывающего абонента не является этим модулем
See Also:
  • canRead(java.lang.Module)

isExported

public boolean isExported(String pn, Module other)

Возвращает true если этот модуль экспортирует данный пакет по крайней мере в данный модуль.

Этот метод возвращает true если вызывается для проверки, экспортируется ли пакет в этом модуле самому себе. Он всегда возвращает true при вызове безымянного модуля. Пакет, open для данного модуля, считается экспортированным в этот модуль во время выполнения, поэтому этот метод возвращает true

, если пакет открыт для данного модуля.

Этот метод не проверяет,читает ли данный модуль данный модуль.

Parameters:
pn — Имя пакета
other — Другой модуль
Returns:
true если этот модуль экспортирует пакет по крайней мере в данный модуль
See Also:
  • ModuleDescriptor.exports()
  • addExports(String,Module)

isOpen

public boolean isOpen(String pn, Module other)

Возвращает true если этот модуль открыл пакет по крайней мере для данного модуля.

Этот метод возвращает значение true , если вызывается для проверки того, открыт ли пакет в этом модуле для самого себя. Он возвращает

true при вызове open модуля с пакетом в модуле. Он всегда возвращает true при вызове безымянного модуля.

Этот метод не проверяет,читает ли данный модуль данный модуль.

Parameters:
pn — Имя пакета
other — Другой модуль
Returns:
true если этот модуль открыл пакет по крайней мере для данного модуля
See Also:
  • ModuleDescriptor.opens()
  • addOpens(String,Module)
  • AccessibleObject.setAccessible(boolean)
  • MethodHandles.privateLookupIn(java.lang.Class<?>, java.lang.invoke.MethodHandles.Lookup)

isExported

public boolean isExported(String pn)

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

Этот метод всегда возвращает true при вызове безымянного модуля.

Пакет, который opened безоговорочно, считается экспортированным безоговорочно во время выполнения, поэтому этот метод возвращает true , если пакет открыт безоговорочно.

Этот метод не проверяет,читает ли данный модуль данный модуль.

Parameters:
pn — Имя пакета
Returns:
true если этот модуль экспортирует пакет безоговорочно
See Also:
  • ModuleDescriptor.exports()

isOpen

public boolean isOpen(String pn)

Возвращает true , если этот модуль безоговорочно открыл пакет.

Этот метод всегда возвращает true при вызове безымянного модуля. Кроме того, он всегда возвращает true при вызове open модуля с пакетом в модуле.

Этот метод не проверяет,читает ли данный модуль данный модуль.

Parameters:
pn — Имя пакета
Returns:
true если этот модуль открыл пакет безоговорочно
See Also:
  • ModuleDescriptor. opens()

addExports

public Module addExports(String pn, Module other)

Если модуль вызывающей стороны является этим модулем,то обновите этот модуль,чтобы экспортировать данный пакет в данный модуль.

Этот метод не действует, если пакет уже экспортирован (или открыт ) в данный модуль.

API Note:
Как указано в разделе 5.4.3Спецификация виртуальной машины Java, если попытка разрешить символическую ссылку не удалась из-за ошибки связывания, то последующие попытки разрешить ссылку всегда терпят неудачу с той же ошибкой, которая была выдана в результате первоначальной попытки разрешения.
Parameters:
pn — Имя пакета
other — Модуль
Returns:
this module
Throws:
IllegalArgumentException — если pn имеет значение null или это именованный модуль, а пакет pn не является пакетом в этом модуле
IllegalCallerException — если это именованный модуль, а модуль вызывающего абонента не является этим модулем
SeeСпецификация виртуальной машины Java:
5. 4.3 Resolution
See Also:
  • isExported(String,Module)

© 1993, 2022, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian’s OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Module.html


OpenJDK 19
  • max

  • cosh

  • addOpens

  • Class Configuration

  • 1
  • 352
  • 353
  • 354
  • 355
  • 356
  • 6528
  • Next

Сервисы модуля Java 9 — CoderLessons.

com

Проводка и поиск

В Java уже давно есть класс ServiceLoader . Он был представлен в 1.6, но с тех пор около Java 1.2 использовалась похожая технология. Некоторые программные компоненты использовали его, но использование не было широко распространено. Он может быть использован для модульности приложения (и даже больше) и для обеспечения возможности расширения приложения с помощью каких-либо плагинов, которые не зависят от времени компиляции приложения. Кроме того, конфигурация этих сервисов очень проста: просто укажите путь к классу / модулю. Мы увидим детали.

Загрузчик службы может найти реализации некоторых интерфейсов. В среде EE есть другие методы для настройки реализаций. В среде, не относящейся к EE, Spring стал вездесущим, что имеет аналогичное, хотя и не совсем то же решение, что и аналогичная, но не совсем та же проблема. Инверсия управления (IoC) и инъекции зависимостей (DI), предоставляемые Spring, являются решением для конфигурации проводки различных компонентов и представляют собой лучшую отраслевую практику, как отделить описание / код проводки от фактической реализации функций, которые классы должны выполнять.

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

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

Возможно, из-за этого большинство приложений, по крайней мере те, которые я видел, не разделяют проводку и обнаружение реализации. Эти приложения обычно используют конфигурацию Spring для поиска и подключения, и это просто нормально. Хотя это упрощение, мы должны жить с ним и быть счастливыми. Мы не должны разделять две функции только потому, что можем. Большинство приложений не должны разделять их. Они аккуратно сидят на простой строке XML-конфигурации приложения Spring.

Мы должны программировать на уровне абстракции, который необходим, но никогда не должен быть более абстрактным.

Да, это предложение является перефразировкой высказывания, приписываемого Эйнштейну. Если вы думаете об этом, вы также можете понять, что это утверждение – не что иное, как принцип KISS (пусть оно будет простым и глупым). Код, а не вы.

ServiceLoader находит реализацию определенного класса. Не все реализации, которые могут быть на пути к классам. Он находит только те, которые «рекламируются». (Я расскажу позже, что означает «рекламируемый».) Программа на Java не может пройти через все классы, которые находятся в пути к классам, или они могут?

Просмотр пути к классам

Этот раздел немного обходится, но важно понять, почему ServiceLoader работает так, как он работает, даже до того, как мы обсудим, как он работает.

Код Java не может запросить загрузчик классов, чтобы получить список всех классов, которые находятся в пути к классам. Вы можете сказать, что я лгу, потому что Spring просматривает классы и автоматически находит кандидатов на реализацию. Весна на самом деле обманывает. Я расскажу вам, как это происходит. Пока что признайте, что путь к классам не может быть просмотрен. Если вы посмотрите на документацию класса ClassLoader вы не найдете ни одного метода, который бы возвращал массив, поток или коллекцию классов. Вы можете получить массив пакетов, но вы не можете получить классы даже из пакетов.

Причиной этому является уровень абстракции того, как Java обрабатывает классы. Загрузчик классов загружает классы в JVM, и JVM все равно откуда. Это не предполагает, что фактические классы находятся в файлах. Есть много приложений, которые загружают классы, а не из файла. На самом деле, большинство приложений загружают некоторые классы с разных носителей. Также ваши программы, вы просто не можете знать это. Вы когда-нибудь использовали Spring, Hibernate или какой-то другой фреймворк? Большинство из этих сред создают прокси-объекты во время выполнения и загружают эти объекты из памяти, используя специальный загрузчик классов. Загрузчик классов не может сказать вам, будет ли когда-либо новый объект, созданный платформой, которую он поддерживает. В данном случае путь к классам не является статическим. Для этих специальных загрузчиков классов даже не существует classpath. Они находят классы динамически.

Ладно. Хорошо сказано и подробно описано. Но опять же: как Spring находит классы? Весна на самом деле делает смелое предположение. Предполагается, что загрузчик классов является специальным: URLClassLoader . ( Как пишет Николай Парлог в своей статье, с Java 9 это уже не так.) Он работает с classpath, который содержит URL-адреса, и может возвращать массив URL-адресов.

ServiceLoader не делает такого предположения и поэтому не просматривает классы.

Как ServiceLoader находит класс

ServiceLoader может находить и создавать экземпляры классов, которые реализуют определенный интерфейс. Когда мы вызываем статический метод ServiceLoader.load(interfaceKlass) , он возвращает «список» классов, которые реализуют этот интерфейс. Я использовал «список» между кавычками, потому что технически он возвращает экземпляр ServiceLoader , который сам реализует Iterable поэтому мы можем перебирать экземпляры классов, которые реализуют интерфейс. Итерация обычно выполняется в цикле for вызывая метод load() после двоеточия (:).

Для успешного поиска экземпляров файлы JAR, содержащие реализации, должны иметь специальный файл в каталоге META-INF/service имеющий полное имя интерфейса. Да, в имени есть точки, и нет никакого конкретного расширения имени файла, но, тем не менее, это должен быть текстовый файл. Он должен содержать полное имя класса, который реализует интерфейс в этом файле JAR.

ServiceLoader вызывает метод findResources для получения URL-адресов файлов и считывает имена классов, а затем снова запрашивает ClassLoader для загрузки этих классов. Классы должны иметь открытый конструктор с нулевым аргументом, чтобы ServiceLoader мог создавать каждый из них.

Наличие в этих файлах имен классов для совмещения загрузки классов и создания экземпляров с использованием загрузки ресурсов работает, но это не слишком элегантно.
Java 9, сохраняя надоедливое решение META-INF/services представила новый подход. С введением Jigsaw у нас есть модули, а модули имеют дескрипторы модулей. Модуль может определить сервис, который может загрузить ServiceLoader и модуль также может указать, какие сервисы ему могут понадобиться для загрузки через ServiceLoader . Этот новый способ обнаружения реализации интерфейса службы перемещается из текстовых ресурсов в код Java. Чистым преимуществом этого является то, что ошибки кодирования, связанные с неправильными именами, могут быть идентифицированы во время компиляции или во время загрузки модуля, чтобы ускорить сбой кода.

Чтобы сделать вещи более гибкими или просто сделать их бесполезно более сложными (будущее покажет), Java 9 также работает, если класс не является реализацией интерфейса службы, но имеет public static provider() метод public static provider() который возвращает экземпляр класса который реализует интерфейс. (Между прочим, в этом случае класс провайдера может даже реализовать интерфейс службы, если он этого хочет, но, как правило, это фабрика, так зачем это делать. Обратите внимание на SRP.)

Образец кода

Вы можете скачать мультимодульный проект Maven с https://github.com/verhas/module-test .

Этот проект содержит три модуля Consumer , Provider и ServiceInterface . Потребитель вызывает ServiceLoader и использует службу, которая определяется интерфейсом javax0.serviceinterface.ServiceInterface в модуле ServiceInterface и реализуется в модуле Provider . Структуру кода можно увидеть на следующем рисунке:

Файлы module-info содержат объявления:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

module Provider {

    requires ServiceInterface;

    provides javax0. serviceinterface.ServiceInterface

      with javax0.serviceprovider.Provider;

}

 

module Consumer {

    requires ServiceInterface;

    uses javax0.serviceinterface.ServiceInterface;

}

 

module ServiceInterface {

    exports javax0.serviceinterface;

}

Ловушки

Здесь я расскажу вам о некоторых глупых ошибках, которые я совершил во время создания этого очень простого примера, чтобы вы могли учиться на моих ошибках, а не повторять их. Прежде всего, в документации по Java 9 в ServiceLoader которое гласит:

Кроме того, если служба не находится в модуле приложения, то объявление модуля должно иметь директиву require, которая указывает модуль, который экспортирует службу.

Я не знаю, что он хочет сказать, но то, что это значит для меня, не соответствует действительности. Может быть, я неверно истолковал это предложение, что вполне вероятно.

В нашем примере модуль Consumer использует нечто, реализующее интерфейс javax0.serviceinterface.ServiceInterface . Это что-то, на самом деле является модулем Provider и его реализацией, но оно решается только во время выполнения и может быть заменено любой другой подходящей реализацией. Таким образом, он нуждается в интерфейсе и, следовательно, должен иметь директиву require в информационном файле модуля, для которого требуется модуль ServiceInterface . Для этого не требуется модуль Provider ! Модуль Provider аналогичным образом зависит от модуля ServiceInterface и должен требовать его. Модуль ServiceInterface ничего не требует. Он экспортирует только пакет, содержащий интерфейс.

Также важно отметить, что ни модуль Provider ни модуль Consumer не обязаны экспортировать какой-либо пакет. Provider предоставляет сервис, объявленный интерфейсом и реализованный классом, названным в честь ключевого слова with в файле информации модуля. Он предоставляет этот единственный класс для всего мира и ничего больше. Чтобы обеспечить только этот класс, было бы излишним экспортировать пакет, содержащий его, и это, возможно, излишне открыло бы классы, которые могут происходить в том же пакете, но являются внутренним модулем. Consumer вызывается из командной строки с помощью параметра –m , и он также не требует, чтобы модуль экспортировал какой-либо пакет.
Команда, как запустить программу

1

2

3

4

java -p Consumer/target/Consumer-1. 0.0-SNAPSHOT.jar:

  ServiceInterface/target/ServiceInterface-1.0.0-SNA

  PSHOT.jar:Provider/target/Provider-1.0.0-SNAPSHOT.

  jar -m Consumer/javax0.serviceconsumer.Consumer

и это может быть выполнено после успешной команды установки mvn . Обратите внимание, что плагин компилятора maven должен быть как минимум версии 3.6, иначе ServiceInterface-1.0.0-SNAPSHOT.jar будет находиться в пути к классам вместо пути к модулю во время компиляции, и во время компиляции не будет найдена информация о module-info.class файл module-info.class .

Какой смысл

ServiceLoader можно использовать, когда приложение подключено к некоторым модулям только во время выполнения. Типичным примером является приложение с плагинами. Я сам столкнулся с этим упражнением, когда портировал ScriptBasic для Java с Java 7 на Java 9. Интерпретатор языка BASIC может быть расширен классами, содержащими общедоступные статические методы, и их необходимо аннотировать как BasicFunction . В последней версии требовалось, чтобы хост-приложение встраивало интерпретатор в список всех классов расширений, вызывающих API в коде. Это лишнее и не нужно. ServiceLoader может найти реализацию службы, для которой интерфейс ( ClassSetProvider ) определен в основной программе, а затем основная программа может вызывать реализации службы одну за другой и регистрировать классы, возвращаемые в наборах. Таким образом, хост-приложению не нужно ничего знать о классах расширений, достаточно, чтобы классы расширений помещались в путь модуля и каждый из них предоставлял услугу.

Сам JDK также использует этот механизм для определения местоположения регистраторов. Новый Java 9 JDK содержит класс System.LoggerFinder который может быть реализован как сервис любым модулем, и если есть реализация, ServiceLoader может найти метод System.getLogger() который найдет это. Таким образом, протоколирование не привязано к JDK, не привязано к библиотеке во время компиляции. Достаточно предоставить регистратор во время выполнения и приложение, библиотеки, которые использует приложение, и JDK будут использовать одно и то же средство ведения журнала.

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

Опубликовано на Java Code Geeks с разрешения Питера Верхаса, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Java 9 Module Services

Мнения, высказанные участниками Java Code Geeks, являются их собственными.

модулей — Dev.java

Главная > Учебники > Модули


  1. Введение в модули в Java

    Понимание основ модульной системы, способов создания и сборки модулей, а также повышения удобства сопровождения и инкапсуляции.

  2. Рефлективный доступ с открытыми модулями и открытыми пакетами

    Используйте открытые пакеты и открытые модули, чтобы разрешить отражающий доступ к инкапсулированным пакетам.

  3. Необязательные зависимости с требуют статического

    Использование требует статического для необязательных зависимостей — модули, требуемые таким образом, доступны во время компиляции, но могут отсутствовать во время выполнения.

  4. Подразумеваемая читаемость с требует транзитивного

    Использование требует транзитивного , чтобы подразумевать читаемость, когда модуль передает свою зависимость от другого модуля, позволяя другим модулям читать его без явной зависимости от него.

  5. Квалифицированный экспортирует и открывает

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

  6. Разделение модулей со службами

    Разделение пользователей и поставщиков службы с помощью Java ServiceLoader API, который модульная система делает первоклассной концепцией с использованием и предоставляют директивы в объявлении модуля.

  7. Код в пути к классу — безымянный модуль

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

  8. Инкрементная модульность с автоматическими модулями

    Простые JAR-файлы на пути к модулям становятся автоматическими модулями, где они могут действовать как мост от модульных JAR-файлов к пути к классам.

  9. Сборка модулей в командной строке

    Узнайте, как использовать команды javac, jar и java для компиляции, упаковки и запуска вашего модульного приложения вручную — полезно знать, хотя инструменты сборки выполняют большую часть тяжелой работы.

  10. Надежная инкапсуляция (внутренних компонентов JDK)

    Надежная инкапсуляция является краеугольным камнем модульной системы. Это позволяет избежать (случайного) использования внутренних API, в основном закрытых типов/членов в java.* пакетов и большая часть sun.* и com.sun.* .

  11. Обход строгой инкапсуляции с помощью --add-exports и --add-opens

    Флаги командной строки --add-exports и --add-opens предоставляют доступ к внутреннему API, будь то часть JDK или зависимость, экспортируя пакет во время компиляции или выполнения или открывая его для отражения во время выполнения.

  12. Расширение графа модулей с помощью --add-modules и --add-reads

    Параметры командной строки --add-modules и --add-reads расширяют граф модулей, сгенерированный модульной системой, с помощью дополнительные модули (узлы) и отношения читабельности (ребра).

Вернуться к списку учебных пособий

Использование Java 9 и более поздних версий с помощью Eclipse JDT

Мир вокруг Java меняется быстрыми темпами. Java теперь выпускается раз в два года, это началось в марте 2018 года. Java 10 была выпущена в марте 2018 года, а Java 11 ожидается в сентябре 2018 года. Не так давно, в сентябре 2017 года, у нас была Java 9.выпускать. Ежеквартальные выпуски Eclipse IDE в марте, июне, сентябре и декабре помогут обеспечить выпуск новой версии Java без особых задержек. Последняя версия Eclipse Photon теперь доступна и поддерживает Java 9 и Java 10. В нее добавлены компилятор, пользовательский интерфейс и запущена поддержка Java 9 и Java 10. разрешенные методы по умолчанию в интерфейсе, а Java 9 разрешает закрытые и статические методы в интерфейсах. Это поможет программистам сохранять повторно используемые коды в частных методах интерфейса.

2. Усовершенствования Try-With Resources — Java 8 требует создания переменной для блока try-with resources. Java 9 позволяет размещать окончательные и фактически окончательные переменные в блоках try-with-resource.

3. @SafeVarargs Аннотации для частных методов экземпляра — Java 7 разрешает @SafeVarargs аннотации для конечных и статических методов и конструкторов. Java 9 также позволяет использовать аннотацию @SafeVarargs для методов частного экземпляра. Его нельзя использовать для общедоступных методов экземпляра.

4. Методы фабрики коллекций . В Java 9 добавлены простые способы создания неизменяемых коллекций без нулевых значений путем предоставления набора из методов .of . Созданная коллекция не должна иметь нулевых значений и не должна изменяться позже, чтобы избежать исключений во время выполнения.

5. Улучшения Stream — в Java 9 добавлены новые API для Stream.

  • Улучшения Stream — в Java 9 добавлены новые API для Stream. Итерация потока — к методу итерации можно добавить условие завершения.
  • Stream takeWhile — takeWhile — это еще один способ добавить завершающее условие в метод итерации.
  • Stream dropWhile — dropWhile отбрасывает подмножество элементов из потока до тех пор, пока оно не будет соответствовать указанному условию.
  • Stream ofNullable — метод ofNullable возвращает последовательный поток с одним значением, только если поток не равен нулю. Этот метод помогает программистам избежать добавления проверок null в Stream.

6. Опция —выпуск – выпуск Java 9. –выпуск . В Eclipse IDE, если у вас есть Java 9 в пути сборки, вы по-прежнему можете использовать параметр –release вместе с уровнем соответствия 1.6 или выше для рабочей области или проекта. Без этого параметра, когда Java 1.8 находится на пути сборки и уровень соответствия установлен как 1.7, база кода по-прежнему компилируется с API-интерфейсами, доступными с Java 1.8 JRE, найденной на пути. Это доступно только в том случае, если путь сборки имеет JRE 9 или более позднюю версию и используется уровень соответствия 1.6 или более поздней версии. Это также означает, что Eclipse не нужен файл дескриптора EE, и правила доступа по умолчанию для библиотек JRE больше не требуются. Обе эти вещи могут быть достигнуты с помощью –опция выпуска .

7. Модули – Project Jigsaw представил систему модулей платформы Java 9. Модуль — это повторно используемая группа связанных пакетов с уникальным именем, а также ресурсы и дескриптор модуля (module-info.java)
. Все модули JDK начинаются с «jdk.*». Все модули спецификаций Java SE начинаются с «java.*». Модульная система Java 9 имеет модуль «java.base» , который является независимым модулем.

В Eclipse поддерживается множество функций пользовательского интерфейса, которые помогают программистам Java использовать модули Java.

В Eclipse IDE модульный проект Java можно создать с помощью меню «Новый проект Java», для которого по умолчанию для параметра «Создать модуль-info.java» установлено значение «истина». Пользователи могут указать имя модуля для проекта Java. Они также могут создать/обновить файл module-info.java позже, используя доступное меню настройки.

Поиск в Java теперь включает новую область поиска — Модуль.

Java Build Path позволяет добавлять проекты и jar-файлы в Modulepath или Classpath.

Модульный узел изменяется на Не модульный, если библиотека проекта «Путь сборки» перемещается в путь к классам.

Свойства инкапсуляции элементов Modulepath могут быть изменены с помощью узла Is module. Модули могут быть ограничены путем явного добавления модулей, —add-reads и —add-exports могут быть добавлены к пакетам в модуле. Его можно использовать для исправления модуля.

Eclipse IDE предоставляет быстрое исправление в module-info.java для импорта класса и добавления требований к module-info.java.

Если запись пути сборки, указанная в Classpath, используется в module-info.java, Eclipse IDE предложит переместить запись classpath в modulepath.

Eclipse IDE предоставляет быстрое исправление в классе для добавления требований к module-info.java.

Рабочая область Eclipse предоставляет быстрое исправление при импорте для добавления требований к module-info. java.

8. Запуск с Java 9 и более поздними версиями — поскольку страница «Путь сборки Java» поддерживает путь к модулю и путь к классу, запустите диалоговое окно конфигурации для Java 9.и далее добавил эту поддержку через вкладку Зависимости .

9. Переопределение зависимостей при запуске для Java 9 и более поздних версий — диалоговое окно «Переопределить зависимость» позволяет пользователю переопределять правила инкапсуляции, такие как исправление, добавление экспорта, добавление операций чтения, ограничение модулей для запуска.

Диалоговое окно показывает зависимости, полученные из пути сборки, и дает возможность переопределить их.

Вот пример смешивания немодульного кода в именованном модуле:

Тестовый файл Junit 5 в тестовой папке находится вне области действия модуля и требует исправления модуля и —add-reads для модуль ВСЕМ-БЕЗНАМЕННЫМ.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *