package me.andy.practice.annotation;import oracle.jrockit.jfr.openmbean.RecordingType;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)public @interface ClassAnnotation { String name();}
package me.andy.practice.annotation;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.METHOD)public @interface MethodAnnotation { String value(); Class<?> type() default java.lang.String.class;}
package me.andy.practice.annotation;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.FIELD)public @interface FiledAnnotation { String value();}
@interface表示這是一個annotation類型
@Retention提供三種策略
RetentionPolicy.RUNTIME:表示不僅在源碼階段,編譯階段會儲存註解資訊,在運行時也會把註解信心加入的JVM中。
RetentionPolicy.CLASS:在源碼階段,編譯階段會儲存註解資訊。註解@Retention預設值。
RetentionPolicy.SOURCE:在源碼階段儲存註解資訊。
@Target表示在Java結構中什麼元素使用註解
TYPE(類型)、FIELD(屬性)、METHOD(方法)、PARAMETER(參數)、CONSTRUCTOR(建構函式)、LOCAL_VARIABLE(局部變數),、PACKAGE(包),其中的TYPE(類型)是指可以用在Class,Interface,Enum和Annotation類型上。
package me.andy.practice.annotation;import java.lang.reflect.InvocationTargetException;@ClassAnnotation(name = "andy")public class Home { public Home() throws InvocationTargetException, IllegalAccessException { super(); AnnotationUtils.init(this); } @FiledAnnotation(value = "name") private String name; @FiledAnnotation(value = "7") private int count; public String getName() { return name; } @MethodAnnotation(value = "andy") public void setName(String name) { this.name = name; } public int getCount() { return count; } @MethodAnnotation(type=java.lang.Integer.class,value = "7") public void setCount(int count) { this.count = count; }}
package me.andy.practice.annotation;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class AnnotationUtils { public static void init(Object o) throws InvocationTargetException, IllegalAccessException { Class<? extends Object> aClass = o.getClass(); Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method method : declaredMethods) { if (method.isAnnotationPresent(MethodAnnotation.class)) { System.out.println(method.getName()); MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class); Class<?> type = annotation.type(); System.out.println(type); System.out.println(annotation.value()); if (type.equals(java.lang.Integer.class)) { method.invoke(o, Integer.valueOf(annotation.value())); } else { method.invoke(o, annotation.value()); } } } }}
package me.andy.practice.annotation;import org.junit.Test;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import static junit.framework.Assert.assertEquals;public class AnnotationTest { @Test public void should_test_utils() throws InvocationTargetException, IllegalAccessException { Home home = new Home(); AnnotationUtils.init(home); assertEquals("andy", home.getName()); assertEquals(7, home.getCount()); }}