java自定义注解与反射

java注解与反射
一、Java中提供了四种元注解,专门负责注解其他的注解,分别如下
  1、@Retention元注解,表示需要在什么级别保存该注释信息(生命周期)。可选的RetentionPoicy参数包括:
    RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉
    RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认)
    RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注解的信息
  2、@Target元注解,默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
    ElementType.CONSTRUCTOR: 构造器声明
    ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
    ElementType.LOCAL_VARIABLE: 局部变量声明
    ElementType.METHOD: 方法声明
    ElementType.PACKAGE: 包声明
    ElementType.PARAMETER: 参数声明
    ElementType.TYPE: 类、接口(包括注解类型)或enum声明
  3、@Documented将注解包含在JavaDoc中
  4、@Inheried允许子类继承父类中的注解

二、注解的定义
  1、注解定义的格式
    public @interface FieldMeta {}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 颜色枚举
     * @author peida
     *
     */
    public enum Color{ BULE,RED,GREEN};
    
    /**
     * 颜色属性
     * @return
     */
    Color fruitColor() default Color.GREEN;

}

三,使用

public class Apple {
    
    @FruitName("Apple")
    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;
    
   }

4、反射 结合使用
 

定义了一个可以作用于类、接口、枚举上的注解MyType。
Documented
@Target({ ElementType.TYPE})
@Retention(RUNTIME)
public @interface MyType {

    String value() default "";
    String className() default "";
}

定义了一个可以作用于类的方法上的注解MyMethod。
@Documented
@Target({ ElementType.METHOD})
@Retention(RUNTIME)
public @interface MyMethod {
    String value() default "";
    String methodName() default "";

}

定义了一个可以作用于类内部变量的注解MyField。
@Documented
@Target({ ElementType.FIELD})
@Retention(RUNTIME)
public @interface MyField {

    String value() default "";
    String name() default "";
    String type() default"String";

}

下面我们写个例子,定义一个类使用这些注解。
@MyType(value = "test", className = "TestClass")
public class TestClass {

    @MyField(value = "testNum", name="num", type = "int")
    private int num;

    @MyField(value = "testName", name="name", type = "String")
    private String name;

    @MyMethod(value = "print ")
    public String print(){
        return "hello annotation";
    }
}

下面我们写一个类来实现读取注解属性并打印出来。
public class PrintAnnotation {

    private String allAnnotation = new String();

    public String printAllAnnotation(){
        Set<Class<?>> clazzes = new Reflections("com.monkey01").getTypesAnnotatedWith(MyType.class);

        for (Class<?> clazz : clazzes) {
            printMyType(clazz);
        }
        System.out.println(allAnnotation);
        return allAnnotation;
    }

    private void printMyType(Class<?> clazz) {
        MyType myType = clazz.getAnnotation(MyType.class);
        allAnnotation = allAnnotation + clazz.getName() + ": " + myType.value() + "-" + myType.className() + "\n";
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields){
            MyField myField = field.getAnnotation(MyField.class);
            if(myField != null) {
                allAnnotation = allAnnotation + myField.value() + "-" + myField.name() + "-" + myField.type() + "\n";
            }
        }
        Method[] methods = clazz.getMethods();
        for(Method method : methods){

            MyMethod myMethod = method.getAnnotation(MyMethod.class);
            if(myMethod != null) {
                allAnnotation = allAnnotation + myMethod.methodName() + "-" + myMethod.value() + "\n";
            }
        }

    }

}

从代码可以看到首先通过反射来获取com.monkey01包下的使用了MyType注解的类。
 Set<Class<?>> clazzes = new Reflections("com.monkey01").getTypesAnnotatedWith(MyType.class);

 public static void getField(){       
        try {
            Class clazz= Class.forName("com.http.model.HttpRequest");
            Field[] field=clazz.getDeclaredFields();
            //System.out.println(field.length);
            for(Field f:field){
                boolean isExist=f.isAnnotationPresent(FieldMeta.class);
                if(isExist){
                    FieldMeta tt=f.getAnnotation(FieldMeta.class);
                    System.out.println("--注解:"+tt.id()+"  "+tt.name());
                }
                System.out.println(f.getName());
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
    

//反射获取对象方法名称
  public static void getMethod(){       
        try {
            Class clazz = Class.forName("com.http.model.HttpRequest");
            Method[] method=clazz.getDeclaredMethods();
            System.out.println(method.length);
            for(Method f:method){
                System.out.println(f.getName());    //获取方法名
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值