Kotlin menyediakan sejumlah anotasi bawaan yang memengaruhi kompilasi, interop Java, dan metadata runtime. Beberapa anotasi mengubah cara kompilator menghasilkan bytecode; yang lain sekadar menandai deklarasi agar dibaca reflection. Pada chapter ini kita akan membedah tujuh anotasi paling sering dipakai: @Deprecated, @JvmStatic, @JvmField, @JvmOverloads, @Nullable, @NonNull, serta meta-annotation @Target dan @Retention. Pemahaman ini menjadi fondasi sebelum kita membuat anotasi custom pada chapter berikutnya.
Tujuh Anotasi yang Sering Dipakai #
| Anotasi | Tempel | Efek |
|---|---|---|
@Deprecated | Function, property, class | Menandai API lama; kompilator memunculkan warning saat dipanggil. |
@JvmStatic | Member object/companion | Menghasilkan static method Java pada class pembungkus. |
@JvmField | Property | Mengekspos field langsung tanpa getter/setter Java. |
@JvmOverloads | Function dengan default arg | Menghasilkan overload Java untuk tiap kombinasi default. |
@Target | Deklarasi anotasi | Membatasi target pemasangan anotasi. |
@Retention | Deklarasi anotasi | Mengatur apakah anotasi disimpan di SOURCE, BINARY, atau RUNTIME. |
@Nullable / @NonNull | Tipe | Menerangkan nullability untuk interop Java. |
Contoh Kode #
Kode berikut memperlihatkan tujuh anotasi di atas dalam aksi:
// File: built_in_annotations.kt
// Mendemonstrasikan anotasi bawaan Kotlin: @Deprecated, @JvmStatic,
// @JvmField, @JvmOverloads, @Target, @Retention.
package com.example.annotasi
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class LogPemakaian(val kategori: String)
object Konfigurasi {
@JvmField
val VERSI: String = "1.0.0"
@JvmStatic
fun ambilNamaAplikasi(): String = "Aplikasi Contoh"
@JvmOverloads
fun sapa(nama: String, salam: String = "Halo", tandaSeru: Boolean = false): String {
val pesan = "$salam, $nama"
return if (tandaSeru) "$pesan!" else pesan
}
}
class RepoLama {
@Deprecated(
message = "Ganti dengan cari(id: Long) yang lebih cepat dan aman.",
replaceWith = ReplaceWith("cari(id)"),
level = DeprecationLevel.WARNING
)
fun cariLama(id: Long): String = "Pengguna lama #$id"
fun cari(id: Long): String = "Pengguna baru #$id"
}
@LogPemakaian("servis")
class LayananPengguna {
fun ambil(id: Long): String = "Pengguna#$id"
}
fun main() {
println("Versi: ${Konfigurasi.VERSI}")
println(Konfigurasi.ambilNamaAplikasi())
println(Konfigurasi.sapa("Budi"))
println(Konfigurasi.sapa("Siti", "Selamat pagi"))
println(Konfigurasi.sapa("Dewi", "Hai", true))
val repo = RepoLama()
// Memakai API baru, bukan yang deprecated.
println(repo.cari(101L))
// Membaca anotasi @LogPemakaian via reflection.
val kelas = LayananPengguna::class
val anotasi = kelas.annotations.find { it is LogPemakaian }
if (anotasi is LogPemakaian) {
println("Anotasi ditemukan: kategori=${anotasi.kategori}")
}
}Output yang Dihasilkan:
Versi: 1.0.0
Aplikasi Contoh
Halo, Budi
Selamat pagi, Siti
Hai, Dewi!
Pengguna baru #101
Anotasi ditemukan: kategori=servisMari kita bedah baris-baris kunci di atas:
- Baris 6-7 (
@Target+@Retention): dua anotasi ini adalah meta-annotation yang menentukan perilaku anotasiLogPemakaian.@Targetmembatasi tempatLogPemakaianboleh dipasang;@Retentionmenentukan apakah anotasi bertahan hingga runtime. - Baris 11 (
@JvmField val VERSI): menginstruksikan kompilator agar tidak membuat getter/setter Java untuk properti ini. Dari sisi Java,Konfigurasi.VERSIlangsung diakses sebagai field public. - Baris 14 (
@JvmStatic fun ambilNamaAplikasi): menghasilkan static method pada class JavaKonfigurasi(selain pada instance object). Java caller menulisKonfigurasi.ambilNamaAplikasi()tanpa harus melewatiINSTANCE. - Baris 17 (
@JvmOverloads fun sapa): function memiliki tiga parameter dengan dua default value.@JvmOverloadsmembuat kompilator menghasilkan tiga overload Java:sapa(nama),sapa(nama, salam), dansapa(nama, salam, tandaSeru). Tanpa anotasi ini, kode Java hanya melihat satu versi penuh. - Baris 27 (
@Deprecated): menandaicariLamasebagai API lama.replaceWith = ReplaceWith("cari(id)")memberikan saran otomatis yang dapat diaplikasikan IntelliJ IDEA.level = DeprecationLevel.WARNINGmemunculkan warning kompilasi;ERRORmenjadikannya galat,HIDDENmenyembunyikan API dari completion. - Baris 38 (
@LogPemakaian("servis")): anotasi custom ditempel pada class. Karena retention RUNTIME, anotasi dapat dibaca via reflection pada baris 54-57.
@Deprecated dan Levelnya #
@Deprecated adalah anotasi paling sering dipakai pada library. Tiga level yang tersedia:
WARNING(default): kompilator menampilkan warning, kode tetap berjalan.ERROR: kompilator menolak pemakaian; konsumen dipaksa bermigrasi.HIDDEN: deklarasi tidak terlihat dari IDE completion, tetapi tetap ada di bytecode.
@JvmStatic dan @JvmField untuk Interop Java #
Saat library Kotlin dipanggil dari Java, kedua anotasi ini sangat berguna. @JvmStatic membuat method object/companion terlihat sebagai static method Java. @JvmField membuat property terlihat sebagai field public biasa. Tanpa keduanya, kode Java harus menulis Konfigurasi.INSTANCE.ambilNamaAplikasi() dan konfigurasi.getVERSI() — lebih verbose.
Referensi Lanjutan #
- Annotations
— panduan resmi anotasi bawaan Kotlin seperti
@Deprecated,@JvmStatic, dan@JvmField
Selanjutnya #
Setelah mengenal anotasi bawaan, kita akan membuat anotasi sendiri — topik chapter Custom Annotations.