直接上代码,注释中有说明:
1、定义自定义注解类(类注解和字段注解):
package com.uno.ray;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.Authenticator.RequestorType;
/**
* 自定义注解
* @author Uno
*@Documented:指明该注解可以用于生成doc
*@Inherited:该注解可以被自动继承
*@Retention:指明在什么级别显示该注解:
* RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃
RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略
RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中
@Target:指明该注解可以注解的程序范围
ElementType.TYPE 用于类,接口,枚举但不能是注解
ElementType.FIELD 作用于字段,包含枚举值
ElementType.METHOD 作用于方法,不包含构造方法
ElementType.PARAMETER 作用于方法的参数
ElementType.CONSTRUCTOR 作用于构造方法
ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句
ElementType.ANNOTATION_TYPE 作用于注解
ElementType.PACKAGE 作用于包
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})//次注解作用于类和字段上
public @interface FieldTypeAnnotation {
/**
*leip 2016年12月3日
*TODO
**/
String type() default "ignore";
int age() default 27;
String[] hobby(); //没有指定defalut的,需要在注解的时候显式指明
}
2、(方法注解)
package com.uno.ray;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author Uno
*
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) //次注解只能作用于方法上
public @interface MethodAnnotation {
String desc() default "method1";
}
3、定义测试类:(反射类)
package com.uno.ray;
import java.awt.Dialog.ModalityType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
@FieldTypeAnnotation(type = "class", hobby = { "smoke" })
public class ReflectAnnotation {
/**
* leip 2016年12月3日 TODO
**/
@FieldTypeAnnotation(hobby = { "sleep", "play" })
private String maomao;
@FieldTypeAnnotation(hobby = { "phone", "buy" }, age = 27, type = "normal")
private String zhangwenping;
@MethodAnnotation()
public void method1() {
}
@MethodAnnotation(desc="method2")
public void method2() {
}
public static void main(String[] args) {
// 此处要用反射将字段中的注解解析出来
Class<ReflectAnnotation> clz = ReflectAnnotation.class;
// 判断类上是否有次注解
boolean clzHasAnno = clz.isAnnotationPresent(FieldTypeAnnotation.class);
if (clzHasAnno) {
// 获取类上的注解
FieldTypeAnnotation annotation = clz.getAnnotation(FieldTypeAnnotation.class);
// 输出注解上的属性
int age = annotation.age();
String[] hobby = annotation.hobby();
String type = annotation.type();
System.out.println(clz.getName() + " age = " + age + ", hobby = " + Arrays.asList(hobby).toString() + " type = " + type);
}
// 解析字段上是否有注解
// ps:getDeclaredFields会返回类所有声明的字段,包括private、protected、public,但是不包括父类的
// getFields:则会返回包括父类的所有的public字段,和getMethods()一样
Field[] fields = clz.getDeclaredFields();
for(Field field : fields){
boolean fieldHasAnno = field.isAnnotationPresent(FieldTypeAnnotation.class);
if(fieldHasAnno){
FieldTypeAnnotation fieldAnno = field.getAnnotation(FieldTypeAnnotation.class);
//输出注解属性
int age = fieldAnno.age();
String[] hobby = fieldAnno.hobby();
String type = fieldAnno.type();
System.out.println(field.getName() + " age = " + age + ", hobby = " + Arrays.asList(hobby).toString() + " type = " + type);
}
}
//解析方法上的注解
Method[] methods = clz.getDeclaredMethods();
for(Method method : methods){
boolean methodHasAnno = method.isAnnotationPresent(MethodAnnotation.class);
if(methodHasAnno){
//得到注解
MethodAnnotation methodAnno = method.getAnnotation(MethodAnnotation.class);
//输出注解属性
String desc = methodAnno.desc();
System.out.println(method.getName() + " desc = " + desc);
}
}
}
}
4、输出
com.uno.ray.ReflectAnnotation age = 27, hobby = [smoke] type = class
maomao age = 27, hobby = [sleep, play] type = ignore
zhangwenping age = 27, hobby = [phone, buy] type = normal
method2 desc = method2
method1 desc = method1