@ Сохранение аннотаций проверки типов Java

Аннотации типов Java 8 (JSR 308) позволяют средствам проверки типов выполнять статический анализ кода. Например, https://checkerframework.org/ может проверять возможную пустоту с помощью @NonNull аннотаций.

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

Для таких аннотаций я бы ожидал @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 просто для того, чтобы избежать зависимостей во время выполнения, кажется грязным хаком.

2 ответа

Решение

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

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

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

Вы отметили это с @Retention(RetentionPolicy.CLASS), "код не имеет никаких зависимостей во время выполнения от соответствующей библиотеки". Это на самом деле верно с @Retention(RetentionPolicy.RUNTIME), тоже! Посмотрите этот вопрос переполнения стека: Почему пропущенная аннотация не вызывает ClassNotFoundException во время выполнения?,

В итоге, используя CLASS Хранение требует незначительного объема пространства во время выполнения, обеспечивает более потенциальное использование в будущем и не вводит зависимость во время выполнения.

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

У каждой аннотации есть своя цель!

javax.validation.constraints.NotNull

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

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

С Уважением,

Лоик

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