Что такое аннотации и как ими пользоваться

Аннотации в Android (и в Java/Kotlin в целом) — это специальные метаданные, которые могут быть добавлены к кодовым элементам (классам, методам, полям, параметрам, и т.д.) для предоставления дополнительной информации компилятору, инструментам разработки или во время выполнения программы. Аннотации не изменяют поведение кода напрямую, но могут влиять на его обработку другими инструментами.

Основные цели использования аннотаций:

  1. Документация: Аннотации могут служить для документирования кода, указывая на определенные свойства методов или классов (например, устаревшие методы).

  2. Валидация на этапе компиляции: Аннотации могут использоваться для выполнения проверок на этапе компиляции (например, аннотации @NonNull, @Nullable).

  3. Управление поведением во время выполнения: Некоторые аннотации могут влиять на выполнение кода при использовании с определенными фреймворками (например, аннотации в Android для работы с архитектурными компонентами).

  4. Генерация кода: С помощью аннотаций можно автоматически генерировать код или ресурсы на этапе компиляции (например, @BindView из ButterKnife или @Inject из Dagger).

Примеры в Android

@NonNull и @Nullable

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

fun greetUser(@NonNull name: String) {
    println("Hello, $name!")
}

fun printLength(@Nullable text: String?) {
    if (text != null) {
        println("Length: ${text.length}")
    } else {
        println("Text is null")
    }
}

@Override

Эта аннотация указывает, что метод переопределяет метод суперкласса. Если метод с аннотацией @Override не соответствует ни одному методу суперкласса, компилятор выдаст ошибку.

class MyActivity : Activity() {
    @Override
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
    }
}

Аннотации для архитектурных компонентов

Аннотации играют важную роль в архитектурных компонентах Android, таких как Room, LiveData, ViewModel.

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "user_name") val name: String
)

@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :userId")
    fun getUserById(userId: Int): LiveData<User>

    @Insert
    fun insertUser(user: User)
}

Аннотации для зависимостей

Пример: Dagger/Hilt

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://example.com")
            .build()
    }
}

Создание собственных аннотаций

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class LogExecutionTime
  • @Target определяет, где может применяться аннотация (например, к функциям, классам, полям и т.д.).
  • @Retention указывает, как долго аннотация будет сохраняться (например, только в исходном коде, в байт-коде, или до выполнения программы).