Рубрики
Без рубрики

Аннотации Kotlin / Java: Они там, где это @

Как понять аннотации Kotlin / Java и примеры правильного использования. Помеченный kotlin, java, аннотацией.

Недавно у меня был интересный разговор с коллегой об использовании аннотаций в коде Java/Kotlin. Он работал в организациях, где использование некоторых языковых функций (в данном случае метапрограммирование с помощью аннотаций) не поощрялось как “слишком волшебное” и “трудное для понимания”. ” Хотя разумно избегать некоторых функций фреймворка или языка, поскольку они обычно считаются вредными, “магия” одного разработчика – это повседневный инструмент повышения производительности другого разработчика.

Я переформулирую возражение против “магии” по-другому:

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

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

Для чего нужны Аннотации?

На высоком уровне аннотации предоставляют компилятору информацию о коде, который он компилирует, чтобы программист мог изменить его поведение (вот почему мы используем термин “метапрограммирование”) или предоставить дополнительную информацию о выполняемом коде во время выполнения. Некоторые аннотации могут служить для генерации ошибок компиляции или предупреждений или даже для генерации большего количества кода для компиляции компилятором в сочетании с процессорами аннотаций (которые работают во время компиляции).

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

Какую общую выгоду предоставляют аннотации?

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

Как используются аннотации?

Насколько я могу судить, их использование можно разбить на следующие три категории (я использую свою собственную номенклатуру):

  • Рынки (БИНАРНЫЕ ОПЦИОНЫ/КЛАСС)
  • Обогащает (ВРЕМЯ ВЫПОЛНЕНИЯ)
  • Генераторы (ИСТОЧНИК)

Маркеры

Маркеры не очень сексуальны, но они все равно важны. Они оба информируют читателя (кода) о природе языкового элемента (например, класс, тип, поле/свойство. и т.д.), который был аннотирован и информирует инструменты статического анализа или компилятор о аннотированном элементе. Они всегда включаются в файлы классов (это то, что подразумевается под сохранением аннотаций . ДВОИЧНЫЙ | |/Политика удержания. КЛАСС перечисление), чтобы их использование публиковалось вместе с любым файлом jar, созданным на основе кода.

@Устаревший в Java – это маркер, который предназначен для того, чтобы сообщить разработчику, что этот элемент исчезнет, и написание любого нового кода, использующего этот элемент, может добавить вам больше работы в будущем, поскольку вы будете вынуждены мигрировать (обычно при обновлении основной версии). Некоторые идеи используют эту аннотацию, чтобы дать понять пользователю, что элемент устарел. @Устаревший в Kotlin был улучшен, чтобы разработчик мог предоставить @replaceWith участника, который позволит некоторым IDE (IntelliJ/Android Studio) разумно заменять устаревший код на не устаревший код. Но в основном это инструмент для читателя кода.

Еще одна полезная аннотация маркера в Java (хотя у нее есть политика сохранения. ВРЕМЯ ВЫПОЛНЕНИЯ) равно @Nonnull (что является частью итогов JSR-305 ). Если вы используете реализацию Google, эта аннотация окажется полезной при взаимодействии Java/Kotlin, потому что ваш код Kotlin сможет определить, что @Nonnull строка foo является Строка в Котлине, а не Строка? . Это также помогает в инструментах статического анализа (таких как findbugs), так что проверки на нуль могут быть пропущены. В случае, если вам было интересно, у этой аннотации есть компаньон в @Nullable .

Обогащенный

Обогатители добавляют информацию к элементу языка, который читается во время выполнения (таким образом, эти аннотации имеют Аннотациювнимание. ВРЕМЯ ВЫПОЛНЕНИЯ /|/Политика удержания. ВРЕМЯ ВЫПОЛНЕНИЯ ). Скажем, например, что вы разрабатывали пользовательскую библиотеку сериализации/десериализации XML с намерением избежать необходимости для ваших потребителей писать пользовательские классы сериализатора/десериализатора. Затем вы можете использовать небольшой набор аннотаций в сочетании с одним сериализатором/десериализатором, который считывает информацию, содержащуюся в аннотациях к элементу (элементам) классов, предназначенных для сериализации в/из. Существует библиотека, которая делает это: http://simple.sourceforge.net/ .

Моя личная любимая библиотека, которая использует аннотации во время выполнения, – это (Retrofit2) [ https://square.github.io/retrofit/ ]. Retrofit 2 использует отражение для создания прокси-объектов Java, способных выполнять сетевой вызов исключительно на основе объявления вашего метода. Например,

public interface UserService {
  @POST("users/new")
  Call createUser(@Body User user);
}

СООБЩЕНИЕ @ и @Body аннотации считываются во время выполнения при выполнении вызова, и когда этот вызов выполняется, retrofit соберет URL-адрес, соответствующий конечной точке в аннотации @POST , и создаст запрос HTTTP, который имеет некоторую сериализованную форму Пользователь объект в теле запроса. (Если вы не знаете, как настроить модернизацию для этого, я предлагаю ознакомиться с документацией).

Это довольно здорово, не так ли? В частности, на Android, Сохранение аннотаций. ВРЕМЯ ВЫПОЛНЕНИЯ /|/Политика удержания. ВРЕМЯ ВЫПОЛНЕНИЯ аннотации имеют стоимость: https://blog.nimbledroid.com/2016/02/23/slow-Android-reflection.html . Поэтому, прежде чем вы начнете использовать их для всего – по крайней мере, в проекте Android, – имейте в виду связанные с этим затраты.

Генераторы

И Kotlin, и Java имеют возможность обработки аннотаций. Процессоры аннотаций запускаются при компиляции вашего проекта (и, таким образом, только они имеют доступ к аннотациям с помощью Аннотацииотзыв. ИСТОЧНИК /|/Политика удержания. ИСТОЧНИК ). Они могут делать такие простые вещи, как добавление заметок, которые выводятся в консоль, или такие сложные, как генерация кода для компиляции. Генераторы особенно применимы в ситуациях, когда традиционные шаблоны повторного использования выходят из строя, и полезны для устранения шаблонного кода.

Например, если вы когда-либо реализовывали шаблон builder, чтобы упростить создание экземпляра класса со многими полями и сделать его более самодокументируемым, то вы, вероятно, знакомы с шаблоном, связанным с ним. Вы обнаружите, что довольно часто проходите через процесс копирования-вставки-изменения. После 10 или 20 повторений этого потока вы, вероятно, где-то допустили ошибку. Затем, чтобы написать разумные методы equals , Хэш-код и toString , вам придется повторить этот процесс еще три раза. Вам также придется написать конструктор, который понимает, как применить конструктор для создания вашего объекта, не назначая случайно неправильное поле конструктора неправильному полю класса.

Введите удивительный обработчик аннотаций автоматического значения Google: https://github.com/google/auto/blob/master/value/userguide/builders.md . Этот инструмент позволяет вам объявить абстрактную версию вашего класса и абстрактную версию конструктора для класса, делегируя детали реализации обработчику аннотаций. Кроме того, также генерируются методы equals , Хэш-код и toString и конструктор для класса.

Предположим, теперь вам нужно добавить поле в класс. Вместо того, чтобы беспокоиться о поддержании актуальности реализации методов конструктора, equals, hashCode и toString, вам просто нужно объявить абстрактный метод для класса и его конструктора. В следующий раз, когда вы скомпилируете свой код, фактическая реализация будет обновлена.

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

Сериализация является естественным продолжением автоматического значения, и довольно много расширений генерируют сериализаторы/десериализаторы объектов классов, которые генерируются с помощью автоматического значения. Я выделю auto-value-moshi в этой статье в качестве репрезентативной библиотеки, потому что существует дополнительный процессор аннотаций Kotlin, называемый moshi-codegen это будет работать и генерировать классы Kotlin для сериализации/десериализации ваших объектов Kotlin в/из JSON.

Вывод

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

Аннотации – полезный инструмент для повышения производительности в Kotlin/Java и повышения качества кода при правильном использовании. Поэтому в следующий раз, когда вы увидите какой-нибудь Java/Kotlin с @ , я надеюсь, что вы будете более способны понять

Оригинал: “https://dev.to/ryansgot/kotlin-java-annotations-they-re-where-it-s-anl”