您的位置:首页 > 编程语言 > Java开发

java自定义注解和运行时靠反射机制获取注解

2016-06-22 14:03 666 查看
java自定义注解:java注解是附加在代码上的一些元信息,用于一些工具在编译,运行时进行解析和使用,起到说明配置的功能。注解不会也不能影响代码的实际逻辑,只起到辅助的作用,包含在java.lang.annotation中。

元注解:指注解的注解。包括@Retetion @Target @Ducument&@Inherited.

1.1、@Retention: 定义注解的保留策略

@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含

@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,

@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

注解类:

[java] view
plain copy







@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;

}

实体类:

[java] view
plain copy







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;

}

}

获取到注解的帮助类:

[java] view
plain copy







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;

}

}

运行时获取注解,首先创建一个基类:

[java] view
plain copy







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;

}

}

创建子类继承基类:

[java] view
plain copy







public class Child extends Parent<Anno>{

}

测试类:

[java] view
plain copy







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());

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java