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