JEP 120: Repeating Annotations
Повторяющиеся аннотации
| Автор | Joseph D. Darcy |
| Ответственный | Alex Buckley |
| Тип | Feature |
| Область | SE |
| Статус | Closed / Delivered |
| Выпуск | 8 |
| Компонент | specification / language |
| JSRs | 269 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 могут помочь ограничить влияние на совместимость на уровне исходного кода.
-
Производительность и масштабируемость: если эта возможность не используется, скорость компиляции не должна снижаться.