2016-08-16 3 views
2

Аннотации типа Java 8 (JSR 308) позволяют проверять тип проверки статического кода. Например, The Checker Framework может проверить на наличие возможных nullness через @NonNull аннотации.@ Версии аннотаций проверки типов Java

Различные проекты определяют свои собственные ненулевым аннотаций, например:

  • org.checkerframework.checker.nullness.qual.NonNull
  • edu.umd.cs.findbugs.annotations.NonNull
  • javax.annotation.Nonnull
  • javax.validation.constraints.NotNull
  • lombok.NonNull
  • org.eclipse.jdt.annotation.NonNull
  • и т.д. (см The Checker Framework Manual, section 3.7)

Для таких аннотаций, я ожидал бы @interface иметь @Retention(RetentionPolicy.CLASS), потому что они, как правило, не требуется во время выполнения. Самое главное, что код не имеет зависимостей времени выполнения от соответствующей библиотеки.

Хотя org.eclipse.jdt.annotation.NonNull следует этому подходу, большинство других ненулевого аннотаций, как javax.annotation.Nonnull (JSR 305) и org.checkerframework.checker.nullness.qual.NonNull самих, имеет @Retention(RetentionPolicy.RUNTIME). Есть ли какая-то конкретная причина для RetentionPolicy.RUNTIME в этих аннотациях?


Уточнение: Checker Framework поддерживает аннотации комментариев для обратной совместимости. Однако использование тех, что в Java 8, чтобы избежать зависимостей во время выполнения, похоже на грязный взлом.

ответ

3

Это хороший вопрос.

Для целей статической проверки во время компиляции CLASS хранения было бы достаточно. Обратите внимание, что удержание SOURCE было бы недостаточным из-за отдельной компиляции: при проверке типа класса компилятор должен читать аннотации в библиотеках, которые он использует, а библиотеки с раздельной компиляцией доступны компилятору только как файлы классов.

Дизайнеры аннотаций использовали удержание RUNTIME, чтобы позволить инструментам выполнять операции во время выполнения. Это может включать в себя проверку аннотаций (например, утверждение assert), проверку типов динамически загруженного кода, проверку операций и instanceof операций, более точное отражение отражения и многое другое. Сегодня не так много таких инструментов, но дизайнеры аннотаций хотели разместить их в будущем.

Вы отметили, что с @Retention(RetentionPolicy.CLASS) «код не имеет зависимостей во времени выполнения от соответствующей библиотеки». Это действительно так: @Retention(RetentionPolicy.RUNTIME), тоже! См. Этот вопрос переполнения стека: Why doesn't a missing annotation cause a ClassNotFoundException at runtime?.

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

В случае Checker Framework он предлагает тесты времени выполнения, такие как isRegex(String). Если ваш код использует такие методы, ваш код будет зависеть от библиотеки времени выполнения Checker Framework (которая меньше, чем вся сама Checker Framework).

+0

Связанное примечание для насмешливых аннотированных классов с mockito (версия 2.2.0): Хотя RetentionPolicy. RUNTIME означает, что аннотация, содержащаяся в двоичном формате, не должна быть доступна во время выполнения, https://bugs.openjdk.java.net/browse/JDK-8152174 вызывает исключение NullPointerException в Java 8, когда высмеивает аннотированный класс, для которого аннотация недоступна в пути к классам. –

1

Каждая аннотация имеет свою цель!

javax.validation.constraints.NotNull 

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

@ RetentionPolicy.SOURCE => обычно используется для документации @ RetentionPocily.CLASS => позволяет предоставить некоторую информацию компилятору, но не JVM (например, для генерации кода во время компиляции) @ RetentionPolicy.RUNTIME => allow для получения информации аннотации на уровне JVM (так что во время выполнения).

С уважением,

Лоик

+0

Да 'javax.validation.constraints.NotNull' имеет цель выполнения. Но 'javax.annotation.Nonnull' и' org.checkerframework.checker.nullness.qual.NonNull' не имеют времени выполнения IMO. –

+1

На ваш вопрос нет глобального ответа. Разработчик аннотации должен определить, нужно ли его сохранять во время выполнения или нет. См. Эту тему SOW для некоторого намека: http://stackoverflow.com/questions/14810030/javax-annotation-nonnull-vs-assert – loicmathieu

Смежные вопросы