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

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 {

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;

}

}

创建子类继承基类:

public class Child extends Parent{

}

测试类:

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

}

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值