Android 利用反射和 注解 进行基础类型封装
在android开发中会遇到基础类型封装,例如数据库的model类型,Http请求的参数类型等,各种注解的应用,可以简化代码,在这里记录一下基本数据的反射和注解的基本应用。
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字节码文件中存在,在运行时可以通过反射获取到
2、大概代码如下
注解类Param
package com.ming.an; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法 @Documented//说明该注解将被包含在javadoc中 /** * 参数类 * @author dell * */ public @interface Param { /** * 是否非空 * @return */ boolean isNotNull() default false; /** * 字段名称 * @return */ String name() default ""; }
获取注解的参数等方法类
package com.ming.an; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * 获取注解的参数等方法类 * @author dell * */ public class AnParam { @SuppressWarnings("unchecked") public static List<AnParam> init(Class clazz) { List<AnParam> list = new ArrayList<AnParam>(); /** * getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void) * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。 * getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 [0]就是这个数组中第一个了。。 * 简而言之就是获得超类的泛型参数的实际类型。。 */ // clazz = clazz.getClass().getGenericSuperclass()) // .getActualTypeArguments()[0]; // FieldMeta filed = clazz.getAnnotation(FieldMeta.class); if (clazz != null) { /** * 返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段 * clazz.getFields();只返回对象所表示的类或接口的所有可访问公共字段 * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等; 可看API * */ Field[] fields = clazz.getDeclaredFields(); // for (Field f : fields) { // 获取字段中包含fieldMeta的注解 Param meta = f.getAnnotation(Param.class); if (meta != null) { AnParam sf = new AnParam(meta, f); list.add(sf); } } // 返回对象所表示的类或接口的所有可访问公共方法 Method[] methods = clazz.getMethods(); for (Method m : methods) { Param meta = m.getAnnotation(Param.class); if (meta != null) { AnParam sf = new AnParam(meta, m.getName(), m.getReturnType()); list.add(sf); } } // 这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序 // Collections.sort(list, new FieldSortCom()); Collections.sort(list, new Comparator<AnParam>() { @Override public int compare(AnParam s1, AnParam s2) { // return s1.getMeta().order()-s2.getMeta().order(); return s1.getName().compareTo(s2.getName());// 也可以用compare来比较 } }); } return list; } public AnParam() { } public AnParam(Param meta, Field field) { super(); this.meta = meta; this.field = field; this.name = field.getName(); this.type = field.getType(); } public AnParam(Param meta, String name, Class<?> type) { super(); this.meta = meta; this.name = name; this.type = type; } private Param meta; private Field field; private String name; private Class<?> type; public Param getMeta() { return meta; } public void setMeta(Param 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; } }
以下是测试类
package com.ming.an; public class TestParam1 { @Param( name = "id") public int id; @Param(name = "name") public String name; @Param(name = "age") public int age; @Param(name = "desc", isNotNull = true) public String desc; } package com.ming.an; import java.util.List; public class TestParam2 { @Param( name = "tel") public long tel; @Param(name = "strs",isNotNull=true) public List<String> strs; @Param(name = "testParams") public List<TestParam1> testParams; @Param(name = "tParam", isNotNull = true) public TestParam1 tParam; } package com.ming.an; import java.util.List; public class TestAnnotation { public static void main(String[] args) { dealWithParam(TestParam1.class); dealWithParam(TestParam2.class); } public static void dealWithParam(Class clazz){ List<AnParam> list = AnParam.init(clazz);//获取泛型中类里面的注解 //输出结果 for(AnParam l : list){ System.out.println("类名:"+clazz.getName()+",字段名称:"+l.getName()+"\t字段类型:"+l.getType()+ "\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().isNotNull()); } } }
当你追求卓越的时候,成功会追着你!