JAVA反射与注解实例
1 JAVA反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。或者说,JAVA反射机制指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
2 JAVA 注解
Annotation(注解)是JDK5.0及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)。
3 注解BEAN
自定义注解类,如下:
@Retention(RetentionPolicy.RUNTIME)
public @interface PropertyInfoAnnotation {
public String code(); // 代码
public String name(); // 名称
public long orderNo();// 排序顺序号
};
简单JAVA BEAN如下:
public class BaseMeasureData {
@PropertyNameAnnotation(code="IN",name="指标代码",orderNo=1)
private String iN;
@PropertyNameAnnotation(code="DN",name="维度",orderNo=2)
private String dN;
@PropertyNameAnnotation(code="VV",name="数据值",orderNo=3)
private String vV;
public String getIN() {
return iN;
}
public void setiN(String iN) {
this.iN = iN;
}
public String getDN() {
return dN;
}
public void setdN(String dN) {
this.dN = dN;
}
public String getVV() {
return vV;
}
public void setvV(String vV) {
this.vV = vV;
}
4 注释帮助类
注释管理器,作为访问注释信息的入口,如下:
public class PropertyHelper {
// 用于禁止在类外部用构造函数实例化该类。
private PropertyHelper() {
}
private static PropertyHelper instance=new PropertyHelper();
public static PropertyHelper getInstance(){
return instance;
}
private Map<Class,Map<String,Long>> beanCachePropertyCodeMap=new HashMap<Class,Map<String,Long>>();
/**
* 获取属性代码及排序顺序号。
* @param bean
* @return
*/
public Map<String,Long> getBeanPropertyCode(Object bean){
Map<String,Long> result=null;
result=(Map<String,Long>)this.beanCachePropertyCodeMap.get(bean.getClass());
if(result!=null)
return result;
else{
result=this.propertyCodeParse(bean);
this.beanCachePropertyCodeMap.put(bean.getClass(), result);
}
return result;
}
/**
* 将类的属性代码及排序顺序号保存到内存对象。
* @param bean
* @return
*/
private Map<String,Long> propertyCodeParse(Object bean){
Map<String,Long> result=null;
if(bean==null)
return null;
Field[] fields=bean.getClass().getDeclaredFields();
if ( fields == null) {
return null;
}
result=new HashMap<String,Long>(fields.length);
for (Field field : fields) {
if (field.isAnnotationPresent(PropertyNameAnnotation.class)) {
PropertyNameAnnotation annotation=field.getAnnotation(PropertyNameAnnotation.class);
result.put(annotation.code(), Long.valueOf(annotation.orderNo()));
}
}
return result;
}
/**
* 获取排序的属性代码。
* @return
*/
public String[] getOrderedCode(Object bean) {
final Map<String,Long> map = getInstance().getBeanPropertyCode(bean);
Set<String> set = map.keySet();
String [] result = set.toArray(new String[set.size()]);
Arrays.sort(result, new Comparator<Object>(){
public int compare(Object o1, Object o2) {
return map.get(o1).compareTo(map.get(o2));
}
});
return (String[])result;
}
};
5 反射与注释应用
private void getObjPro(Object obj, Map dataMap, String className) {
Class clas;
if (obj == null) {
clas = Class.forName(className);
obj = clas.newInstance();
} else {
clas = Class.forName(obj.getClass().getName());
}
//得到obj类的所有属性
Field[] fileds = clas.getDeclaredFields();
for (Field field : fileds) {
String fieldName = field.getName();
String fieldType = field.getType().getName();
PropertyNameAnnotation annotation=field.getAnnotation(PropertyNameAnnotation.class);
if (null == annotation) {
return ;
}
String propertyCode = annotation.code();
// 属性名的第一个字母大写,与get或者is组成方法名
String firstCharUpper = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
Method method;
//如果是boolean型则方法名为is*;反之为get*
if (isBooleanType(fieldType)) {
method = clas.getMethod("is" + firstCharUpper, null);
} else {
method = clas.getMethod("get" + firstCharUpper, null);
}
if (isSysDefinedType(fieldType)) {
//如果是系统类型则添加进入map
String formatDateStr = isTimeType(fieldType, method, obj);
if (formatDateStr != null) {
dataMap.put(propertyCode, formatDateStr);
continue;
}
dataMap.put(propertyCode, method.invoke(obj, null) == null ? "" : method.invoke(obj, null)); //执行方法,将结果保存到dataMap。
}
}
}