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()); } }