openjdk.ruOpenJDK на русском

JEP 120: Repeating Annotations

Повторяющиеся аннотации

АвторJoseph D. Darcy
ОтветственныйAlex Buckley
ТипFeature
ОбластьSE
СтатусClosed / Delivered
Выпуск8
Компонентspecification / language
JSRs269 MR, 337
Обсуждениеenhanced dash metadata dash spec dash discuss at openjdk dot java dot net
ТрудоёмкостьS
ДлительностьM
Зависит отJEP 104: Type Annotations
ОдобренBrian Goetz
Создан2011/10/17 20:00
Обновлён2015/02/13 19:40
Задача8046110

Аннотация

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

Цели

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

Мотивация

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

Описание

Основной подход к реализации этой возможности языка — преобразовывать (desugar) повторяющиеся аннотации базового типа в одну аннотацию-контейнер; у аннотации-контейнера есть метод values, который возвращает массив базового типа аннотации. Чтобы повторяющиеся аннотации можно было использовать для конкретного типа аннотации, объявление базового типа аннотации должно будет включать новую мета-аннотацию, например @ContainerAnnotation, которая объявляет, какой другой тип аннотации следует использовать в качестве контейнера. Если контейнер недостаточно совместим с базовой аннотацией, в том числе при проблемных различиях в политике хранения (retention policy) или цели (target), должны выдаваться предупреждения и ошибки.

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

@A(1)
@A(2)
@AContainer
@AContainerContainer
foo();

считать логически эквивалентным

@AContainerContainer(@AContainer({@A(1), @A2}), @AContainer)
foo();

или выдавать ошибку компиляции после одного уровня вложенности в

@AContainer({@A(1), @A(2)})
@AContainer
@AContainerContainer
foo();

На уровне библиотек реализации рефлексивных API платформы, включая базовую рефлексию и javax.lang.model, потребуется обновить, чтобы они обрабатывали информацию о повторяющихся аннотациях. Например, метод AnnotatedElement.getAnnotation(BaseAnnotation.class) будет переопределён так, чтобы искать аннотацию в аннотации-контейнере, если базовая аннотация не присутствует непосредственно. В интерфейс AnnotatedElement может быть добавлен один или несколько методов для проверки наличия или отсутствия аннотаций. Если будет поддерживаться несколько уровней вложенности, генерируемой компилятором, изменения в библиотеках будут более обширными.

Тестирование

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

Риски и допущения

Один из рисков — возможность пока непредвиденных взаимодействий между этой возможностью языка и существующей семантикой библиотек или между этой возможностью языка и другими возможностями языка, присутствующими в Java SE 8. В частности, потребуется определить взаимодействие (если оно есть) между повторяющимися аннотациями и аннотациями на типах.

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

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

Зависимости

Необходимо определить взаимодействие (если оно есть) между повторяющимися аннотациями и JEP 104: Annotations on Java Types.

Влияние

  • Другие компоненты JDK: ожидается, что повторяющиеся аннотации будут напрямую использоваться в кодовой базе JDK минимально.

  • Совместимость: в интерфейсы, у которых обычно не ожидается реализаций за пределами JDK, могут быть добавлены методы. Defender-методы из проекта Lambda могут помочь ограничить влияние на совместимость на уровне исходного кода.

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