Bài 331: Tùy chỉnh Annotation trong java

Ngày đăng: 1/7/2023 11:47:24 AM

Tùy chỉnh annotation trong java hoặc Java annotation được người dùng định nghĩa rất dễ dàng để tạo và sử dụng. Phần tử @interface được sử dụng để khai báo một annotation. Ví dụ:

1     

@interface MyAnnotation {}

Ở đây, chú thích MyAnnotation là tên annotation tùy chỉnh.

Các kiểu của annotation

Có 3 kiểu của annotation:

  1. Marker Annotation
  2. Single-Value Annotation
  3. Multi-Value Annotation

1. Marker Annotation

Một annotation không có phương thức được gọi là marker annotation. Ví dụ:

1      

@interface MyAnnotation{}

@Override và @Deprecated là các maker annotation.


Single-Value Annotation

Một annotation mà có một phương thức được gọi là single-value annotation. Ví dụ:

1

2

3      

@interface MyAnnotation {

    int value();

}

Bạn cũng có thể cung cấp giá trị mặc định, ví dụ:

1

2      

3

@interface MyAnnotation {

    int value() default 0;

}

Làm thế nào để áp dụng Single-Value Annotation

Ví dụ sử dụng Single-Value Annotation:

1      

@MyAnnotation(value = 10)

value có thể là những giá trị khác.


Multi-Value Annotation

Một annotation mà có nhiều hơn một phương thức được gọi là Multi-Value annotation. Ví dụ:

1

2

3

4

5

6

7       

@interface MyAnnotation {

    int value1();

 

    String value2();

 

    String value3();

}

Bạn cũng có thể cung cấp giá trị mặc định, ví dụ:

1

2

3

4

5

6

7      

@interface MyAnnotation {

    int value1() default 1;

 

    String value2() default "";

 

    String value3() default "xyz";

}

Làm thế nào để áp dụng Multi-Value Annotation

Ví dụ sử dụng Multi-Value Annotation:

1      

@MyAnnotation(value1 = 10, value2 = "Hello", value3 = "Java")


Sử dụng annotation tích hợp trong annotation tùy chỉnh trong java

  • @Target
  • @Retention
  • @Inherited
  • @Documented

1. @Target

Thẻ @Target được sử dụng để chỉ định loại nào được sử dụng.

enum java.lang.annotation.ElementType khai báo nhiều hằng số để xác định loại phần tử mà annotation được áp dụng như TYPE, METHOD, FIELD vv. Dưới đây là bảng các hằng số của enum ElementType:

Kiểu phần tử

Trường hợp có thể áp dụng annotation

TYPE

class, interface hoặc enumeration

FIELD

các trường

METHOD

các phương thức

CONSTRUCTOR

các constructor

LOCAL_VARIABLE

biến local

ANNOTATION_TYPE

kiểu annotation

PARAMETER

tham số

Ví dụ chỉ định annoation cho class:

1

2

3

4

5

6

7

8

9     

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

 

@Target(ElementType.TYPE)

@interface MyAnnotation {

    int value1();

 

    String value2();

}

Ví dụ chỉ định annoation cho các class, phương thức và trường:

1

2

3

4

5

6

7

8

9     

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

 

@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD })

@interface MyAnnotation {

    int value1();

 

    String value2();

}


2. @Retention

Thẻ @Retention được sử dụng để chỉ định annotation được sử dụng ở mức độ nào.

Hằng số RetentionPolicy

Khả năng

RetentionPolicy.SOURCE

tham chiếu đến mã nguồn, bị loại bỏ trong quá trình biên dịch. Nó sẽ không có sẵn trong lớp được biên dịch.

RetentionPolicy.CLASS

tham chiếu tới tập tin .class, ó sẵn cho trình biên dịch java nhưng không cho JVM. Nó được bao gồm trong tập tin .class.

RetentionPolicy.RUNTIME

tham chiếu tới thời gian chạy, sẵn có cho trình biên dịch java và JVM.

Ví dụ để chỉ định RetentionPolicy

1

2

3

4

5

6

7

8

9

10

11

12    

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@interface MyAnnotation {

    int value1();

 

    String value2();

}


3. @Inherited

Theo mặc định, các annotation không được kế thừa cho các lớp con. Annotation @Inherited được thừa kế đánh dấu annotation này được kế thừa cho các lớp con.

1

2

3

4

5

6

7

8

9

10

11     

import java.lang.annotation.Inherited;

 

@Inherited

@interface ForEveryone {

    int value();

}

 

@ForEveryone(10)

class Superclass {}

 

class Test extends Superclass {}


4. @Documented

Thẻ @Documented đánh dấu chú thích để đưa vào tài liệu.


Phân tích annotation bằng cách sử dụng reflection

Ví dụ 1: Dưới đây là ví dụ đơn giản sử dụng reflection trong java để lấy giá trị của annotation.

Bạn phải thêm @Retention(RetentionPolicy.RUNTIME) vào để annotation của bạn sử dụng được lúc runtime.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49    

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

import java.lang.reflect.Method;

 

// define annotation for method

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

@interface MyMethodAnnotation {

    int value();

}

 

// define annotation for class

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@interface MyClassAnnotation {

    String classType();

}

 

// Apply annotation

@MyClassAnnotation(classType = "ENTITY")

class Hello {

    @MyMethodAnnotation(value = 10)

    public void sayHello() {

        System.out.println("hello!");

    }

}

 

// Access annotation

class Test {

    public static void main(String args[]) throws Exception {

        // get method

        Method method = Hello.class.getClassLoader()

                .loadClass("vn.viettuts.annotation.Hello")

                .getMethod("sayHello");

        // get annotation from method

        MyMethodAnnotation manno = method

                .getAnnotation(MyMethodAnnotation.class);

        // show value of annotation

        System.out.println("value is: " + manno.value());

 

        // get annotation from class

        MyClassAnnotation canno = Hello.class

                .getAnnotation(MyClassAnnotation.class);

        // show value of annotation

        System.out.println("classType is: " + canno.classType());

    }

}

Kết quả:

 value is: 10
 classType is: ENTITY
 

Ví dụ 2: đây là ví dụ về việc sử dụng @Inherited để cho phép lớp con được phép kế thừa các annotation của lớp cha.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37     

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

// define annotation for class

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@Inherited

@interface MyClassAnnotation {

    String classType();

}

 

// Apply annotation

@MyClassAnnotation(classType = "ENTITY")

class Hello {

    public void sayHello() {

        System.out.println("hello!");

    }

}

 

// Apply annotation for subclass

class Alo extends Hello {

 

}

 

// Access annotation

class Test {

    public static void main(String args[]) throws Exception {

        // get annotation from class "Alo"

        MyClassAnnotation canno = Alo.class

                .getAnnotation(MyClassAnnotation.class);

        // show value of annotation

        System.out.println("classType is: " + canno.classType());

    }

}

Kết quả:

 classType is: ENTITY

Nguồn tin: viettuts.vn