Membuat anotasi adalah proses yang agak mudah, walaupun ia dihadkan oleh beberapa peraturan. Sekarang kita perlu memikirkan tujuan praktikal yang mereka sediakan.

Mari kita ingat kembali cara kita mencipta anotasi kita sendiri.

Kami akan menulis anotasi untuk kelas dan kaedah serta mengandungi maklumat tentang pengarang dan versi kod:


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

Berikut ialah kelas kami yang kami anotasikan:


@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() {}
}

Bagaimanakah kita boleh menggunakan data ini pada masa jalan?

Dengan menggunakan refleksi untuk mengekstrak metadata daripada anotasi. Ingat apa itu refleksi. Refleksi ialah mekanisme untuk memeriksa data tentang program pada masa jalan. Refleksi membolehkan anda mendapatkan maklumat tentang medan, kaedah, pembina kelas dan kelas.

Kami akan menggunakan refleksi untuk membaca anotasi dalam kelas dan memaparkan maklumat yang kami inginkan.

Kami akan membaca data dari kelas kami dalam kaedah 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 menghantar contoh kelas kami kepada kaedah readMyClass .

Kemudian kita boleh lulus kelas serta kaedah kepada kaedah readAnnotation . Mari lakukan itu — kita akan lulus objek Kelas dan objek Kaedah. Ia memerlukan objek yang melaksanakan antara muka AnnotatedElement . Ini membolehkan kami mendapatkan senarai anotasi daripada objek dan mendapatkan maklumat tentang setiap daripadanya.

Harap maklum bahawa kami hanya mendapat maklumat selepas menyemak sama ada anotasi tergolong dalam jenis anotasi kami: if (annotation instanceof Info) .

Output program memberi kami maklumat lengkap daripada anotasi:

Kelas: anotasi.MyClass1
Cari anotasi dalam java.lang.Class
Pengarang:
Versi Pengarang: 0.0
Cari anotasi dalam java.lang.reflect.Method
Pengarang:
Versi Pengarang: 0.0

Kelas: anotasi.MyClass2
Cari anotasi dalam java.lang.
Pengarang Kelas :
Versi Pengarang: 2.0
Cari anotasi dalam java.lang.reflect.Method
Pengarang:
Versi Tanpa Nama: 0.0

Kelas: anotasi.MyClass3
Cari anotasi dalam java.lang.Class
Pengarang:
Versi Tanpa Nama: 2.0
Cari anotasi dalam java. lang.reflect.Kaedah
Pengarang: Tanpa Nama
Versi: 4.0

Oleh itu, dengan bantuan refleksi, kami dapat mengekstrak metadata.

Sekarang mari kita lihat contoh penggunaan anotasi untuk menambah baik kod, termasuk meningkatkan kebolehbacaan, kelajuan dan kualiti secara umum. Lombok akan membantu kami dalam hal ini.

Lombok ialah pemalam pengkompil yang menggunakan anotasi untuk menyembunyikan sejumlah besar kod dan memanjangkan bahasa, dengan itu memudahkan pembangunan dan menambah beberapa fungsi.

Pertimbangkan contoh anotasi dari Lombok:

@Menjalin Menghasilkan pelaksanaan kaedah toString() yang terdiri daripada perwakilan menyeluruh objek: nama kelas, semua medan dan nilainya.

@ToString
public class Example
@EqualsAndHashCode Menghasilkan pelaksanaan equals dan hashCode yang menggunakan medan bukan statik dan bukan statik secara lalai, tetapi boleh dikonfigurasikan. Butiran lanjut boleh didapati di tapak web projek . Di sana anda akan menemui contoh yang menggunakan @EqualsAndHashCode dan juga menunjukkan pelaksanaan standard tanpa anotasi.
@Getter / @Setter Menghasilkan getter dan setter untuk medan persendirian.

@Getter 
@Setter 
private String name = "name";
@NonNull Digunakan untuk menegaskan bahawa medan tidak batal apabila sesuatu objek dijadikan instantiated. Jika tidak, NullPointerException dilemparkan.

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

Lombok mempunyai banyak lagi anotasi berguna yang jarang digunakan. Kami telah mempertimbangkan anotasinya yang paling mudah. Anda boleh membaca lebih lanjut mengenai projek itu di laman web rasmi .