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ụ:
@interface MyAnnotation {}
Ở đây, chú thích MyAnnotation là tên annotation tùy chỉnh.
Nội dung chính
Các kiểu của annotation
Có 3 kiểu của annotation:
- Marker Annotation
- Single-Value Annotation
- Multi-Value Annotation
1. Marker Annotation
Một annotation không có phương thức được gọi là marker annotation. Ví dụ:
@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ụ:
@interface MyAnnotation { int value(); }
Bạn cũng có thể cung cấp giá trị mặc định, ví dụ:
@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:
@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ụ:
@interface MyAnnotation { int value1(); String value2(); String value3(); }
Bạn cũng có thể cung cấp giá trị mặc định, ví dụ:
@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:
@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:
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:
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
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.
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.
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.
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