注解看起来很神秘,其实看穿了就是一种标记,通过运行时获取标记进行后续处理。说到运行时自然离不开反射,所以注解就是反射的一种应用。使用元注解就可以实现自定义注解,元注解只有4个:Retention、Target、Document和Inherited,分别用于标记注解的保留策略、应用目标、是否包含于javadoc、是否允许子类继承。直接看代码:
package com.wulinfeng.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.TYPE) public @interface Type { String name() default ""; }
package com.wulinfeng.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 Element { String value() default ""; }
package com.wulinfeng.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 MethodName { int version() default 0; }
package com.wulinfeng.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.TreeMap; @Type(name = "hello") public class Annotations { Map<Integer, Method> methodMap = new TreeMap<>(); @Element("world") private String name; @MethodName(version = 1) public void logs1(Class<?> clazz) { // 取类注释值 for (Annotation annotation : clazz.getAnnotations()) if (annotation instanceof Type) { name = ((Type) annotation).name(); break; } System.out.println("hello " + name); } @MethodName(version = 2) public void logs2(Class<?> clazz) { // 取字段name的注解值 Field[] fields = Annotations.class.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Element.class)) { Element element = field.getAnnotation(Element.class); name = element.value(); break; } } System.out.println("hello " + name); } // 加载方法版本号映射 public void initialize(Class<?> clazz) { Method[] methods = clazz.getMethods(); for (Method method : methods) { for (Annotation annotation : method.getAnnotations()) { if (annotation instanceof MethodName) { methodMap.put(((MethodName) annotation).version(), method); } } } } // 根据方法版本号获取具体方法,通过反射执行方法 public void execute(int version, Class<?> clazz) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { Method method = methodMap.get(version); Object o = clazz.newInstance(); if (method != null) { method.invoke(o, clazz); } } public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { // 开始测试不同版本号的方法调用 Annotations annotation = new Annotations(); annotation.initialize(Annotations.class); annotation.execute(1, Annotations.class); annotation.execute(2, Annotations.class); } }
运行结果:
hello hello hello world
时间: 2024-11-13 10:14:52