Java註解Annotation使用方法歸納
簡介
註解是從JDK5開始支持,是Java對元數據的一種特殊支持。與註釋有一定區別,可以理解爲代碼上的特殊標記,通過這些標記我們可以在編譯,類加載,運行等程序類的生命週期內被讀取、執行相應的處理。通過註解開發人員可以在不改變原有代碼和邏輯的情況下在源代碼中嵌入補充信息。註解是Java語言的一種強大的功能。
自定義註解
1.編寫自定義註解
- 註解的定義修飾符爲@interface
- 註解中可以添加成員變量,成員變量以方法的形式定義
- 需要使用@Retention註解來規定它的生命週期(編譯期間、運行時等)
- 需要使用@Target註解來規定它的適用範圍(類型、方法、字段、方法參數等)
例子一
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.PARAMETER,
ElementType.TYPE,
ElementType.ANNOTATION_TYPE})
public @interface TestAnnotation {
String value();
}
說明
- @Inherited註解規定了這個自定義註解是可以被繼承的。(父類修飾子類繼承)
- 註解定義中 String value(); 通過方法的方式定義了註解的成員變量value
使用註解進行修飾
- 使用TestAnnotation來給類、成員變量添加註解
- value命名的成員變量可以直接以參數的形式賦值。
@TestAnnotation("Class Student")
public class Student {
@TestAnnotation("constance field")
public static final String CLASS_NAME = "Student";
@TestAnnotation("field")
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
例子二
- 使用 default ${value} 的形式可以定義成員變量是否需要默認值。
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.PARAMETER,
ElementType.TYPE,
ElementType.ANNOTATION_TYPE})
public @interface TestAnnotationTwo {
String message();
String[] names() default {};
}
說明
- 註解定義中 String message(); String[] names(); 通過方法的方式定義了註解的成員變量message和names,其中names爲String數組
使用註解進行修飾
- 非value命名的成員變量需要通過 fieldName = value 來進行賦值
- 註解中可以爲空(具有默認值)的成員變量可以不賦值
@TestAnnotationTwo(message = "Hello!")
public class StudentTwo {
@TestAnnotationTwo(message = "Hi!", names = {"holo", "la"})
private String id;
@TestAnnotationTwo(message = "yes")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
自定義註解處理
- 一般定義好註解的生命週期、成員變量之後,還需要針對註解編寫相應的處理程序,獲取程序的元數據。
註解定義如下
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.PARAMETER,
ElementType.TYPE,
ElementType.ANNOTATION_TYPE})
public @interface TestAnnotation {
String value();
}
使用自定義註解修飾代碼
- 例子中的Student通過@TestAnnotation註解分別修飾了類、字段、方法以及方法參數
@TestAnnotation("Class Student")
public class Student {
@TestAnnotation("constance field")
public static final String CLASS_NAME = "Student";
@TestAnnotation("field")
private String name;
@TestAnnotation("Constructor")
public Student(String name) {
this.name = name;
}
@TestAnnotation("getter")
public String getName() {
return name;
}
@TestAnnotation("setter")
public void setName(String name) {
this.name = name;
}
@TestAnnotation("public method")
public void printName() {
System.out.println(name);
}
@TestAnnotation("public method with parameter")
public void printName(@TestAnnotation("parameter") String name) {
System.out.println(name);
}
}
編寫處理程序獲取元數據
- 獲取類(type)上的註解及其變量value值
public void learnClassAnnotation() {
Class<?> clazzStudent = Student.class;
for (Annotation annotation : clazzStudent.getAnnotations()) {
if (annotation instanceof TestAnnotation) {
System.out.println(((TestAnnotation) annotation).value());
}
if (annotation.annotationType() == TestAnnotation.class) {
System.out.println(((TestAnnotation) annotation).value());
}
}
}
- 結果如下
Class Student
Class Student
- 獲取字段(field)上的註解及其變量value值
public void learnFieldAnnotation() {
Class<?> clazz = Student.class;
List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
fields.forEach(field -> {
System.out.println("\n\n------------------------field " + field.getName());
for (Annotation annotation : field.getAnnotations()) {
if (annotation instanceof TestAnnotation) {
System.out.println(((TestAnnotation) annotation).value());
}
if (annotation.annotationType() == TestAnnotation.class) {
System.out.println(((TestAnnotation) annotation).value());
}
}
});
}
- 結果如下
------------------------field CLASS_NAME
constance field
constance field
------------------------field name
field
field
- 獲取構造器(constructor)上的註解及其變量value值
public void learnConstructorAnnotation() {
Class<?> clazz = Student.class;
List<Constructor<?>> constructors = Arrays.asList(clazz.getDeclaredConstructors());
constructors.forEach(constructor -> {
System.out.println("\n\n------------------------constructor " + constructor.getName());
for (Annotation annotation : constructor.getAnnotations()) {
if (annotation instanceof TestAnnotation) {
System.out.println(((TestAnnotation) annotation).value());
}
if (annotation.annotationType() == TestAnnotation.class) {
System.out.println(((TestAnnotation) annotation).value());
}
}
});
}
- 結果如下
------------------------constructor Student
Constructor
Constructor
- 獲取方法(method)上的註解及其變量value值
public void learnMethodAnnotation() {
Class<?> clazz = Student.class;
List<Method> methods = Arrays.asList(clazz.getMethods());
methods.forEach(method -> {
System.out.println("\n\n------------------------method " + method.getName());
for (Annotation annotation : method.getAnnotations()) {
if (annotation instanceof TestAnnotation) {
System.out.println(((TestAnnotation) annotation).value());
}
if (annotation.annotationType() == TestAnnotation.class) {
System.out.println(((TestAnnotation) annotation).value());
}
}
});
}
- 結果如下
------------------------method getName
getter
getter
------------------------method setName
setter
setter
------------------------method printName
public method
public method
------------------------method printName
public method with parameter
public method with parameter
------------------------method wait
------------------------method wait
------------------------method wait
------------------------method equals
------------------------method toString
------------------------method hashCode
------------------------method getClass
------------------------method notify
------------------------method notifyAll
- 獲取方法參數(parameter)上的註解及其變量value值
public void learnParameterAnnotation() {
Class<?> clazz = Student.class;
List<Method> methods = Arrays.asList(clazz.getMethods());
for (Method method : methods) {
System.out.println("\n\n-----------------------------------------------method " + method.getName());
for (Parameter parameter : method.getParameters()) {
System.out.println("------------------------parameter " + parameter.getName());
for (Annotation annotation : parameter.getAnnotations()) {
if (annotation instanceof TestAnnotation) {
System.out.println(((TestAnnotation) annotation).value());
}
if (annotation.annotationType() == TestAnnotation.class) {
System.out.println(((TestAnnotation) annotation).value());
}
}
}
}
}
- 結果
-----------------------------------------------method getName
-----------------------------------------------method setName
------------------------parameter arg0
-----------------------------------------------method printName
-----------------------------------------------method printName
------------------------parameter arg0
parameter
parameter
-----------------------------------------------method wait
-----------------------------------------------method wait
------------------------parameter arg0
------------------------parameter arg1
-----------------------------------------------method wait
------------------------parameter arg0
-----------------------------------------------method equals
------------------------parameter arg0
-----------------------------------------------method toString
-----------------------------------------------method hashCode
-----------------------------------------------method getClass
-----------------------------------------------method notify
-----------------------------------------------method notifyAll
說明
- 通過反射方式獲取Annotation[]數組之後,可以通過下面兩種方式來判斷此註解是否就是你自定義的註解
1.通過 instanceof 操作,判斷annotation對象是否是自定義註解類
annotation instanceof TestAnnotation
2.通過 Annotation 的 annotationType() 方法獲取到annotation對象的類型,並同自定義註解類進行比對
annotation.annotationType() == TestAnnotation.class
註解處理工具類
- 最後附上註解處理的工具類,定義了若干實用的註解處理方法,希望對朋友們有所幫助
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* Created by xuyh(Johnsonmoon) at 2018/1/3 11:43.
*/
public class AnnotationUtils {
/**
* get declared annotations of the given class
*
* @param clazz given class
* @return annotations
*/
public static Annotation[] getAnnotations(Class<?> clazz) {
return clazz.getAnnotations();
}
/**
* get declared annotations of the given field
*
* @param field given field
* @return annotations
*/
public static Annotation[] getAnnotations(Field field) {
return field.getAnnotations();
}
/**
* get declared annotations of the given method
*
* @param method given method
* @return annotations
*/
public static Annotation[] getAnnotations(Method method) {
return method.getAnnotations();
}
/**
* get declared annotations of the given constructor
*
* @param constructor given constructor
* @return annotations
*/
public static Annotation[] getAnnotations(Constructor constructor) {
return constructor.getAnnotations();
}
/**
* get declared annotations of the given parameter
*
* @param parameter given parameter
* @return annotations
*/
public static Annotation[] getAnnotations(Parameter parameter) {
return parameter.getAnnotations();
}
/**
* Is field has annotation of annotationType
*
* @param field given field
* @param annotationType given annotation type
* @return true/false
*/
public static boolean hasAnnotation(Field field, Class<?> annotationType) {
Annotation[] annotations = field.getAnnotations();
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return true;
}
return false;
}
/**
* Is clazz has annotation of annotationType
*
* @param clazz given clazz
* @param annotationType given annotation type
* @return true/false
*/
public static boolean hasAnnotation(Class<?> clazz, Class<?> annotationType) {
Annotation[] annotations = clazz.getAnnotations();
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return true;
}
return false;
}
/**
* Is method has annotation of annotationType
*
* @param method given method
* @param annotationType given annotation type
* @return true/false
*/
public static boolean hasAnnotation(Method method, Class<?> annotationType) {
Annotation[] annotations = method.getAnnotations();
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return true;
}
return false;
}
/**
* Is constructor has annotation of annotationType
*
* @param constructor given constructor
* @param annotationType given annotation type
* @return true/false
*/
public static boolean hasAnnotation(Constructor<?> constructor, Class<?> annotationType) {
Annotation[] annotations = constructor.getAnnotations();
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return true;
}
return false;
}
/**
* Is parameter has annotation of annotationType
*
* @param parameter given parameter
* @param annotationType given annotation type
* @return true/false
*/
public static boolean hasAnnotation(Parameter parameter, Class<?> annotationType) {
Annotation[] annotations = parameter.getAnnotations();
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return true;
}
return false;
}
/**
* Get annotation of given annotation type declared in given field.
*
* @param field given field
* @param annotationType given annotation type
* @return annotation instance
*/
public static Annotation getAnnotation(Field field, Class<?> annotationType) {
Annotation[] annotations = field.getAnnotations();
if (annotations == null || annotations.length == 0)
return null;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return annotation;
}
return null;
}
/**
* Get annotation of given annotation type declared in given clazz.
*
* @param clazz given clazz
* @param annotationType given annotation type
* @return annotation instance
*/
public static Annotation getAnnotation(Class<?> clazz, Class<?> annotationType) {
Annotation[] annotations = clazz.getAnnotations();
if (annotations == null || annotations.length == 0)
return null;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return annotation;
}
return null;
}
/**
* Get annotation of given annotation type declared in given method.
*
* @param method given method
* @param annotationType given annotation type
* @return annotation instance
*/
public static Annotation getAnnotation(Method method, Class<?> annotationType) {
Annotation[] annotations = method.getAnnotations();
if (annotations == null || annotations.length == 0)
return null;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return annotation;
}
return null;
}
/**
* Get annotation of given annotation type declared in given constructor.
*
* @param constructor given constructor
* @param annotationType given annotation type
* @return annotation instance
*/
public static Annotation getAnnotation(Constructor<?> constructor, Class<?> annotationType) {
Annotation[] annotations = constructor.getAnnotations();
if (annotations == null || annotations.length == 0)
return null;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return annotation;
}
return null;
}
/**
* Get annotation of given annotation type declared in given parameter.
*
* @param parameter given parameter
* @param annotationType given annotation type
* @return annotation instance
*/
public static Annotation getAnnotation(Parameter parameter, Class<?> annotationType) {
Annotation[] annotations = parameter.getAnnotations();
if (annotations == null || annotations.length == 0)
return null;
for (Annotation annotation : annotations) {
if (annotation.annotationType() == annotationType)
return annotation;
}
return null;
}
}