注解是jdk1.5开始提供,允许java程序在运行时读取类的注解信息
运行注解的步骤:
1.首先自定义Annotation注解类型
2.在源代码中使用定义的注解
3.在程序中使用反射读取注解信息
声明一个注解的关键字 @interface
public @interface PersonAnnotatin{
}
上面我们声明了一个注解,但是并没有限定注解的相关使用
@Target:指定注解的适用的目标,有以下几种,可以作用于类、方法、构造器、字段、参数等,使用的时候可以指定多个范围
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
@Retention:限定当前注解的有效范围有RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME
RetentionPolicy.SOURCE:仅存在源代码中,不会把程序中对注解的引用编译到类文件中,作用范围小
RetentionPolicy.CLASS:会把程序中对注解的引用编译到类文件中
RetentionPolicy.RUNTIME:范围最大,包含上面两种情况,还能在运行时把注解加载到java虚拟机中
@Documented:标示性注解,注解类型包含的信息会被加入到javaDoc文档中
构造器注解
@Documented
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConstructorAnnotatin {
String constructorName() default "";
String remark() default "构造器";
}
属性注解
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotatin {
String name() default "";
String remark() default "字段描述";
}
方法注解
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotatin {
String methodName() default "";
String remark() default "方法描述";
}
类注解
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorAnnotatin {
String className() default "这是一个java类";
String description() default "类信息描述";
}
使用注解
@AuthorAnnotatin
public class Person {
@FieldAnnotatin(name="name",remark="姓名")
private String name;
@FieldAnnotatin(name="age",remark="年龄")
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@MethodAnnotatin(methodName="run")
public static void run() {
System.out.println("run方法");
}
@ConstructorAnnotatin(constructorName="Person()")
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
注解解析
public class AnnotationTest {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.xqc.book.test.anno.Person");
System.out.println("==============类注解解析==============");
printClassAnno(clazz);
System.out.println("==============成员变量注解解析==============");
printFieldAnno(clazz);
System.out.println("==============成员方法注解解析==============");
printMethodAnno(clazz);
System.out.println("==============构造器注解解析==============");
printConstructorAnno(clazz);
}
/**
* 打印类的注解
*/
private static void printClassAnno(Class<?> clazz) throws ClassNotFoundException {
//判断是否有AuthorAnnotatin注解
if(clazz.isAnnotationPresent(AuthorAnnotatin.class)) {
//获取AuthorAnnotatin类型的注解
AuthorAnnotatin annotation = clazz.getAnnotation(AuthorAnnotatin.class);
System.out.println(annotation.className()+"\t"+annotation.description());
}
}
/**
* 打印成员变量的注解
*/
private static void printFieldAnno(Class<?> clazz) throws ClassNotFoundException {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if(field.isAnnotationPresent(FieldAnnotatin.class)) {
FieldAnnotatin annotation = field.getAnnotation(FieldAnnotatin.class);
System.out.println(annotation.name()+"\t"+annotation.remark());
}
}
}
/**
* 打印成员变量的注解
*/
private static void printMethodAnno(Class<?> clazz) throws ClassNotFoundException {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(MethodAnnotatin.class)) {
MethodAnnotatin annotation = method.getAnnotation(MethodAnnotatin.class);
System.out.println(annotation.methodName()+"\t"+annotation.remark());
}
}
}
/**
* 打印成员变量的注解
*/
private static void printConstructorAnno(Class<?> clazz) throws ClassNotFoundException {
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
if(constructor.isAnnotationPresent(ConstructorAnnotatin.class)) {
ConstructorAnnotatin annotation = constructor.getAnnotation(ConstructorAnnotatin.class);
System.out.println(annotation.constructorName()+"\t"+annotation.remark());
}
}
}
}
输出结果