标签:
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。
1.1、@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
注解类:
@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; } }
获取到注解的帮助类
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 Parent<T> { private Class<T> entity; public Parent() { init(); } @SuppressWarnings("unchecked") public List<SortableField> init(){ List<SortableField> list = new ArrayList<SortableField>(); /**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void) * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。 * getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 * [0]就是这个数组中第一个了。。 * 简而言之就是获得超类的泛型参数的实际类型。。*/ entity = (Class<T>)((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<SortableField>() { @Override public int compare(SortableField s1,SortableField s2) { return s1.getMeta().order()-s2.getMeta().order(); // return s1.getName().compareTo(s2.getName());//也可以用compare来比较 } }); } return list; } }
创建子类继承基类:
public class Child extends Parent<Anno>{ }
测试类:
public class TestAnnotation { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Parent c = new Child(); List<SortableField> list = c.init();//获取泛型中类里面的注解 //输出结果 for(SortableField l : list){ System.out.println("字段名称:"+l.getName()+"\t字段类型:"+l.getType()+ "\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().description()); } } }
标签:
原文地址:http://my.oschina.net/kooeasy/blog/475431