一、摘要
java注解(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, ElementType.METHOD, ElementType.FIELD}) public @interface Man { String manName(); int manAge() default 20; }
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 AgeAdder { int addValue(); }
@Man(manName = "Teacher Wang", manAge = 100) public class Teacher { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @AgeAdder(addValue = 10) public void doAddAge(int age) { System.out.println("增加年龄: = " + age); } }
测试:
import javax.annotation.Resource; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class AnnotationTest { public static void main(String[] args) throws Exception { Class<?> clazz = Teacher.class; Teacher teacher = (Teacher) clazz.newInstance(); String name = ""; if (clazz.isAnnotationPresent(Man.class)) { Man man = clazz.getAnnotation(Man.class); name = man.manName(); int age = man.manAge(); System.out.println("被标记为男性教师!"); System.out.println("name = " + name); System.out.println("age = " + age); } Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals("setName")) { methods[i].invoke(teacher, name); } Method method = methods[i]; if (method.isAnnotationPresent(AgeAdder.class)) { AgeAdder ageAdder = method.getAnnotation(AgeAdder.class); int addValue = ageAdder.addValue(); System.out.println("有增加年龄的方法标记: 名称->" + method.getName() + "增加幅度->" + addValue); } } System.out.println("从注解中获取的名字 = " + teacher.getName()); } }
运行结果:
被标记为男性教师! name = Teacher Wang age = 100 有增加年龄的方法标记: 名称->doAddAge 增加幅度->10 从注解中获取的名字 = Teacher Wang
注解起标记作用,如Servlet3.0标准、EJB3.0、 Spring等都支持注解,它们都在类初始化的时候进行特定的注解检查,进而完成特定的业务操作,具体注解检查的工作可以按上文所示使用java的api进行,也可以使用第三方的工具如ASM等进行,OpenEJB、Spring等都使用ASM。
注解的检查时机一般在类加载的时刻,JDK1.5以后的instrument机制(设置javaagent)及1.6以后的探针技术更加方便了注解的检查工作。