通过反射获取注解(Annotation)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

以下实例,定义一个注解。通过反射获取。

主要功能:为所注解过的参数和方法附加一些信息可以获取。

定义注解。

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD, ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface FieldMeta {
    /**
     * 是否为序列号
     *
     * @return
     */
    boolean id() default false;

    /**
     * 字段名称
     *
     * @return
     */
    String name() default "";

    /**
     * 是否可编辑
     *
     * @return
     */
    boolean editable() default true;

    /**
     * 是否在列表中显示
     *
     * @return
     */
    boolean summary() default true;

    /**
     * 字段描述
     *
     * @return
     */
    String description() default "";

    /**
     * 排序字段
     *
     * @return
     */
    int order() default 0;
}
public class Anno {

    @FieldMeta(id = true, name = "序列号", order = 1)
    private int id;
    @FieldMeta(name = "姓名", order = 3)
    private String name;
    @FieldMeta(name = "年龄", order = 2)
    private int age;

    @FieldMeta(description = "描述", order = 4)
    public String desc() {
        return "java反射获取annotation的测试";
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class Parent {
    private Class entity;

    public Parent() {
        init();
    }

    @SuppressWarnings("unchecked")
    public List init() {
        List list = new ArrayList();
        /**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void)
         * 的直接超类的 Type(Class泛型中的类型),然后将其转换ParameterizedType。。
         *  getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
         *  [0]就是这个数组中第一个了。。
         *  简而言之就是获得超类的泛型参数的实际类型。。*/
        entity = (Class) ((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
//      FieldMeta filed = entity.getAnnotation(FieldMeta.class);

        if (this.entity != null) {

            /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
             * entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段
             * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等;
             * 可看API
             * */
            Field[] fields = entity.getDeclaredFields();
//
            for (Field f : fields) {
                //获取字段中包含fieldMeta的注解
                FieldMeta meta = f.getAnnotation(FieldMeta.class);
                if (meta != null) {
                    SortableField sf = new SortableField(meta, f);
                    list.add(sf);
                }
            }

            //返回对象所表示的类或接口的所有可访问公共方法
            Method[] methods = entity.getMethods();

            for (Method m : methods) {
                FieldMeta meta = m.getAnnotation(FieldMeta.class);
                if (meta != null) {
                    SortableField sf = new SortableField(meta, m.getName(), m.getReturnType());
                    list.add(sf);
                }
            }
            //这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序
//          Collections.sort(list, new FieldSortCom());
            Collections.sort(list, new Comparator() {
                @Override
                public int compare(SortableField s1, SortableField s2) {
                    return s1.getMeta().order() - s2.getMeta().order();
//                  return s1.getName().compareTo(s2.getName());//也可以用compare来比较
                }

            });
        }
        return list;

    }
}
import java.lang.reflect.Field;

public class SortableField {

    public SortableField() {
    }

    public SortableField(FieldMeta meta, Field field) {
        super();
        this.meta = meta;
        this.field = field;
        this.name = field.getName();
        this.type = field.getType();
    }


    public SortableField(FieldMeta meta, String name, Class type) {
        super();
        this.meta = meta;
        this.name = name;
        this.type = type;
    }


    private FieldMeta meta;
    private Field field;
    private String name;
    private Class type;

    public FieldMeta getMeta() {
        return meta;
    }

    public void setMeta(FieldMeta meta) {
        this.meta = meta;
    }

    public Field getField() {
        return field;
    }

    public void setField(Field field) {
        this.field = field;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }


}
public class Anno {

    @FieldMeta(id = true, name = "序列号", order = 1)
    private int id;
    @FieldMeta(name = "姓名", order = 3)
    private String name;
    @FieldMeta(name = "年龄", order = 2)
    private int age;

    @FieldMeta(description = "描述", order = 4)
    public String desc() {
        return "java反射获取annotation的测试";
    }

    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}
public class Child extends Parent {

}
import java.util.List;

public class TestAnnotation {

    @SuppressWarnings({"unchecked", "rawtypes"})
    public static void main(String[] args) {
        Parent c = new Child();
        List list = c.init();//获取泛型中类里面的注解
        //输出结果  
        for (SortableField l : list) {
            System.out.println("字段名称:" + l.getName() + "\t字段类型:" + l.getType() +
                    "\t注解名称:" + l.getMeta().name() + "\t注解描述:" + l.getMeta().description());
        }
    }
}

转载于:https://my.oschina.net/marjeylee/blog/778377

你可能感兴趣的:(通过反射获取注解(Annotation))