Ang paggawa ng mga anotasyon ay medyo simpleng proseso, bagama't nililimitahan ito ng ilang panuntunan. Ngayon ay kailangan nating malaman kung anong praktikal na layunin ang kanilang pinaglilingkuran.

Alalahanin natin kung paano tayo gumagawa ng sarili nating anotasyon.

Magsusulat kami ng anotasyon na para sa mga klase at pamamaraan at naglalaman ng impormasyon tungkol sa may-akda at bersyon ng code:

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

Narito ang aming mga klase na aming na-annotate:

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

Paano natin magagamit ang data na ito sa runtime?

Sa pamamagitan ng paggamit ng reflection upang kunin ang metadata mula sa mga anotasyon. Alalahanin kung ano ang repleksyon. Ang pagninilay ay isang mekanismo para sa pagsusuri ng data tungkol sa isang programa sa runtime. Hinahayaan ka ng Reflection na makakuha ng impormasyon tungkol sa mga field, pamamaraan, constructor ng klase, at mga klase.

Gagamit kami ng reflection para basahin ang mga anotasyon sa isang klase at ipakita ang impormasyong gusto namin.

Babasahin namin ang data mula sa aming mga klase sa pangunahing pamamaraan:

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();
       }
   }
}

Nagpapasa kami ng isang instance ng aming klase sa readMyClass method.

Pagkatapos ay maipapasa natin ang isang klase pati na rin ang isang paraan sa readAnnotation na paraan. Gawin natin iyan — magpapasa tayo ng Class object at Method object. Kinakailangan ang isang bagay na nagpapatupad ng interface ng AnnotatedElement . Nagbibigay-daan ito sa amin na makakuha ng listahan ng mga anotasyon mula sa bagay at makakuha ng impormasyon tungkol sa bawat isa sa kanila.

Tandaan na nakakakuha lang kami ng impormasyon pagkatapos suriin kung ang anotasyon ay kabilang sa aming uri ng anotasyon: if (annotation instanceof Info) .

Ang output ng programa ay nagbibigay sa amin ng kumpletong impormasyon mula sa mga anotasyon:

Class: annotation.MyClass1
Maghanap ng mga anotasyon sa java.lang.Class
May-akda:
Bersyon ng May-akda: 0.0
Maghanap ng mga anotasyon sa java.lang.reflect.Method
May-akda:
Bersyon ng May-akda: 0.0

Class: annotation.MyClass2
Maghanap ng mga anotasyon sa java.lang. Class
Author: Author
Version: 2.0
Search for annotation in java.lang.reflect.Method
Author: Anonymous
Version: 0.0

Class: annotation.MyClass3
Search for annotation in java.lang.Class
Author: Anonymous
Version: 2.0
Search for annotation in java. lang.reflect.Method
Author: Anonymous
Version: 4.0

Kaya, sa tulong ng pagmuni-muni, nakuha namin ang metadata.

Ngayon tingnan natin ang isang halimbawa ng paggamit ng mga anotasyon upang mapabuti ang code, kabilang ang pagtaas ng pagiging madaling mabasa, bilis, at kalidad sa pangkalahatan. Tutulungan tayo ng Lombok dito.

Ang Lombok ay isang compiler plugin na gumagamit ng mga anotasyon upang itago ang isang malaking halaga ng code at palawigin ang wika, sa gayon ay pinapasimple ang pag-unlad at pagdaragdag ng ilang pag-andar.

Isaalang-alang ang isang halimbawa ng mga anotasyon mula sa Lombok:

@ToString Bumubuo ng pagpapatupad ng toString() na pamamaraan na binubuo ng isang masusing representasyon ng object: ang pangalan ng klase, lahat ng field, at ang kanilang mga halaga.
@ToString
public class Example
@EqualsAndHashCode Bumubuo ng mga pagpapatupad ng equals at hashCode na gumagamit ng mga non-static at non-static na field bilang default, ngunit maaaring i-configure. Higit pang mga detalye ay matatagpuan sa website ng proyekto . Doon ay makakahanap ka ng isang halimbawa na gumagamit ng @EqualsAndHashCode at nagpapakita rin ng karaniwang pagpapatupad nang walang anotasyon.
@Getter / @Setter Bumubuo ng mga getter at setter para sa mga pribadong field.
@Getter
@Setter
private String name = "name";
@NonNull Ginagamit upang igiit na ang mga patlang ay hindi null kapag ang isang bagay ay na-instantiate. Kung hindi, isang NullPointerException ang itatapon.
public Example(@NonNull P p) {
 super("Hello");
 this.name = p.getName();
}

Ang Lombok ay may mas maraming kapaki-pakinabang na anotasyon na hindi gaanong ginagamit. Isinaalang-alang namin ang pinakasimpleng anotasyon nito. Maaari mong basahin ang higit pa tungkol sa proyekto sa opisyal na website .