Membuat anotasi adalah proses yang cukup sederhana, meskipun dibatasi oleh beberapa aturan. Sekarang kita perlu mencari tahu tujuan praktis apa yang mereka layani.

Mari kita ingat bagaimana kita membuat anotasi kita sendiri.

Kami akan menulis anotasi untuk kelas dan metode dan berisi informasi tentang pembuat dan versi kode:


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

Inilah kelas kami yang kami anotasi:


@Info
public class MyClass1 {
   @Info
   public void myClassMethod() {}
}
 
@Info(version = "2.0")
public class MyClass2 {
   @Info(author = "Anonymous")
   public void myClassMethod() {}
}
 
@Info(author = "Anonymous", version = "2.0")
public class MyClass3 {
   @Info(author = "Anonymous", version = "4.0")
   public void myClassMethod() {}
}

Bagaimana kita bisa menggunakan data ini saat runtime?

Dengan menggunakan refleksi untuk mengekstrak metadata dari anotasi. Ingat apa itu refleksi. Refleksi adalah mekanisme untuk memeriksa data tentang suatu program saat runtime. Refleksi memungkinkan Anda mendapatkan informasi tentang bidang, metode, konstruktor kelas, dan kelas.

Kami akan menggunakan refleksi untuk membaca anotasi di kelas dan menampilkan informasi yang kami inginkan.

Kami akan membaca data dari kelas kami dalam metode utama :


import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
 
public class Main {
   public static void main(String[] args) throws NoSuchMethodException {
       readMyClass(MyClass1.class);
       readMyClass(MyClass2.class);
       readMyClass(MyClass3.class);
   }
 
   static void readMyClass(Class<?> myClassObj) throws NoSuchMethodException {
       System.out.println("\nClass: " + myClassObj.getName());
       readAnnotation(myClassObj);
       Method method = myClassObj.getMethod("myClassMethod");
       readAnnotation(method);
   }
 
   static void readAnnotation(AnnotatedElement element) {
       try {
           System.out.println("Search for annotations in " + element.getClass().getName());
           Annotation[] annotations = element.getAnnotations();
           for (Annotation annotation : annotations) {
               if (annotation instanceof Info) {
                   final Info fileInfo = (Info) annotation;
                   System.out.println("Author: " + fileInfo.author());
                   System.out.println("Version: " + fileInfo.version());
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Kami meneruskan instance kelas kami ke metode readMyClass .

Kemudian kita bisa meneruskan kelas serta metode ke metode readAnnotation . Mari kita lakukan — kita akan melewatkan objek Class dan objek Metode. Dibutuhkan objek yang mengimplementasikan antarmuka AnnotatedElement . Ini memungkinkan kita mendapatkan daftar anotasi dari objek dan mendapatkan informasi tentang masing-masingnya.

Perhatikan bahwa kami hanya mendapatkan informasi setelah memeriksa apakah anotasi termasuk dalam jenis anotasi kami: if (annotation instanceof Info) .

Output program memberi kami informasi lengkap dari anotasi:

Kelas: annotation.MyClass1
Cari anotasi di java.lang.Class
Penulis: Penulis
Versi: 0.0
Cari anotasi di java.lang.reflect.Method
Penulis: Penulis
Versi: 0.0

Kelas: annotation.MyClass2
Cari anotasi di java.lang. Kelas
Penulis: Penulis
Versi: 2.0
Cari anotasi di java.lang.reflect.Metode
Penulis: Anonim
Versi: 0.0

Kelas: annotation.MyClass3
Cari anotasi di java.lang.Class
Penulis: Anonim
Versi: 2.0
Cari anotasi di java. lang.reflect.Method
Penulis: Anonim
Versi: 4.0

Jadi, dengan bantuan refleksi, kami dapat mengekstrak metadata.

Sekarang mari kita lihat contoh penggunaan anotasi untuk menyempurnakan kode, termasuk meningkatkan keterbacaan, kecepatan, dan kualitas secara umum. Lombok akan membantu kami dalam hal ini.

Lombok adalah plugin kompiler yang menggunakan anotasi untuk menyembunyikan sejumlah besar kode dan memperluas bahasa, sehingga menyederhanakan pengembangan dan menambahkan beberapa fungsi.

Pertimbangkan contoh anotasi dari Lombok:

@ToString Menghasilkan implementasi metode toString() yang terdiri dari representasi objek secara menyeluruh: nama kelas, semua bidang, dan nilainya.

@ToString
public class Example
@EqualsAndHashCode Menghasilkan implementasi sama dengan dan kode hash yang menggunakan bidang non-statis dan non-statis secara default, tetapi dapat dikonfigurasi. Rincian lebih lanjut dapat ditemukan di situs web proyek . Di sana Anda akan menemukan contoh yang menggunakan @EqualsAndHashCode dan juga menampilkan implementasi standar tanpa anotasi.
@Pengambil / @Setter Menghasilkan getter dan setter untuk bidang pribadi.

@Getter 
@Setter 
private String name = "name";
@NonNull Digunakan untuk menyatakan bahwa bidang bukan nol saat objek dibuat. Jika tidak, NullPointerException akan dilempar.

public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Lombok memiliki lebih banyak anotasi bermanfaat yang lebih jarang digunakan. Kami telah mempertimbangkan anotasinya yang paling sederhana. Anda dapat membaca lebih lanjut tentang proyek ini di situs web resmi .