JavaRush /Kurslar /All lectures for UZ purposes /Аннотацияларни рантаймда ишлаш

Аннотацияларни рантаймда ишлаш

All lectures for UZ purposes
Daraja, Dars
Mavjud

Аннотацияларни яратиш — жуда осон жараён, лекин баъзи қоидалар билан чегараланган. Энди улар амалда қаерда фойдали эканлигини тушунишимиз керак.

Келинг, ўз аннотациямизни қандай яратганимизни эслайлик.

Класслар ва методларни аннотация қилиш учун аннотация ёзамиз ва муаллиф ва версия ҳақидаги маълумотларни сақлаймиз:


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

Аннотация қўшган классларимиз:


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

Дастур ишлаётганда бу маълумотларни қандай фойдалансак бўлади?

Аннотациялардан метамаълумотларни рефлексия ёрдамида чиқариб олиш мумкин. Рефлексия нима эканини эслайлик. Бу дастур ишлаётганда ундаги маълумотларни тадқиқ қилиш механизми. Рефлексия қаторлар, методлар, класслар конструкторлари ҳақида маълумот олишга имкон беради.

Рефлексия ёрдамида биз классдаги аннотацияларни ўқиб чиқамыз ва керакли маълумотларни чиқарамиз.

mainдаги классларимиздан маълумотларни билиб оламиз:


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("\nКласс " + myClassObj.getName());
       readAnnotation(myClassObj);
       Method method = myClassObj.getMethod("myClassMethod");
       readAnnotation(method);
   }
 
   static void readAnnotation(AnnotatedElement element) {
       try {
           System.out.println("Поиск аннотаций в " + element.getClass().getName());
           Annotation[] annotations = element.getAnnotations();
           for (Annotation annotation : annotations) {
               if (annotation instanceof Info) {
                   final Info fileInfo = (Info) annotation;
                   System.out.println("Автор: " + fileInfo.author());
                   System.out.println("Версия: " + fileInfo.version());
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

readMyClass методига класснинг экземплярини бериб, уни ишлатамиз.

Кейин readAnnotation методига ҳам класс, ҳам методни беришимиз мумкин. Шундай қилиб, биз класска ва методга объектни ўтамиз. AnnotatedElement контрактини ишлайдиган объект қабул қилинади. Бу аннотациялар рўйхатини ундан чиқариб олишга ва уларнинг ҳар бири ҳақидаги маълумотни ўқишга имкон беради.

Аннотацияни бизнинг аннотация туримизга тегишлилигини текширмасдан, биз маълумотларни ололмаймиз (if (annotation instanceof Info)).

Натижада аннотациялардан тўлиқ маълумот оламиз:

Класс annotation.MyClass1
Поиск аннотаций в java.lang.Class
Автор: Author
Версия: 0.0
Поиск аннотаций в java.lang.reflect.Method
Автор: Author
Версия: 0.0

Класс annotation.MyClass2
Поиск аннотаций в java.lang.Class
Автор: Author
Версия: 2.0
Поиск аннотаций в java.lang.reflect.Method
Автор: Anonymous
Версия: 0.0

Класс annotation.MyClass3
Поиск аннотаций в java.lang.Class
Автор: Anonymous
Версия: 2.0
Поиск аннотаций в java.lang.reflect.Method
Автор: Anonymous
Версия: 4.0

Шундай қилиб, рефлексия ёрдамида метамаълумотларни чиқариб олдик.

Энди кодни яхшилаш учун аннотациялардан фойдаланиш усулларини кўриб чиқамиз, жумладан, ўқишни яхшилаш, ишлаш тезлигини ошириш ва умумий сифатни яхшилаш. Бунда bizga Lombok ёрдам беради.

Lombok — бу компиляторга қўшиладиган плагин бўлиб, аннотация калит сўзлари ёрдамида кўп миқдордаги кодни яширади, тилни кенгайтириб, ишлаб чиқишни соддалаштиради ва баъзи функционалликни қўшади.

Lombok аннотацияларининг мисолини кўриб чиқамиз:

@ToString toString() методи учун амалга оширишни яратади, у объектнинг тозаланган талқинидан иборат: класс номи, барча майдонлар ва уларнинг қийматлари.

@ToString
public class Example
@EqualsAndHashCode equals ва hashCode амалга оширишларни яратади, улар ўзгарувчан ва стационар бўлмаган майдонлардан фойдаланиб, аммо мослаштирилади. Батафсил маълумотни лойиҳа сайтда ўқиш мумкин. У ерда @EqualsAndHashCode билан ва ундан ташқари стандарт амалга ошириш билан мисол келтирилган.
@Getter / @Setter Шахсий майдонлар учун getter ва setter яратади.

@Getter 
@Setter 
private String name = “name”;
@NonNull Объект экземпляри яратилгандан кейин майдонларни null эмаслигини тасдиқлаш учун ишлатилади. Акс ҳолда, NullPointerException истисносидан чиқиб кетилади.

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

Lombok устида кўпроқ фойдали аннотациялар мавжуд, лекин улар камдан кам ишлатилади. Биз унинг аннотацияларининг бошланғич қисмини кўриб чикдик. Лойиҳа ҳақида кўпроқ маълумотни расмий сайтдан ўқиш мумкин.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION