有的时候,我们在开发的时候,由于要考虑到代码的重用性,自然而然的就会想到用反射来处理一些问题。
借用:java反射机制应用场景 一文
反射机制实现:
1)导出文件(1-4)
2)结果集在页面的显示(在运行时构造任意一个类的对象):显示哪些列, 操作按钮权限的显示(在类中定义一个显示权限的属性真或假,在得到的结果集后调用反射机制和权限控制-得到真或假,在页面中进行判断)
1、在运行时判断任意一个对象所属的类。
Class cls = Class.forName("com.jdk");
返回true
System.out.print(cls.isInstance(new jdk()));
2、在运行时构造任意一个类的对象。
Class cls = Class.forName("com.jdk");
jdk jdkobj = cls.newInstance();
3、在运行时判断任意一个类所具有的成员变量和方法。
Class cls = Class.forName("com.jdk");
Methods methods[]= cls.getDecliedMethod();
Fields fields[] = cls.getDeclieredFields();
4、在运行时调用任意一个对象的方法
Class cls = Class.forName("com.jdk");
Methods methods[]= cls.getDecliedMethod();
jdk jdkobj = new jdk();
String returnvalue = methods.invoke(jdkobj,null)
其中第四种方法最长使用:
主要有:
a.配置文件创建form对象。并初始化。
1、使用配置文件产生类的实例。通过配置文件中提供的名称生成类的实例。
2、使用类的实例,根据request中的参数生成一个properties文件,之后使用beanUtils.populte(form,pro);
对form的属性进行复制,其中就是使用reflect方法。
b.当你不知道要创建什么类型的对象时,使用在运行时提供类的完整路径的方式来生成类的实例时,
例如:
在struts中对messageResources引用的生成中,使用到工厂方法的模式,对于他所要使用的工厂,他采用的是factoryClass参数来生成工厂,之后使用这个工厂的实例来生成messageResources对象。
这其中就使用到了使用reflect产生类的实例。
c.当对象的方法只有在运行时才知道那些方法被调用,那些方法不用调用时,且方法遵循一定的规律生成,而且方法很对,比如100个。
例如:
使用日历生成客户经理的月报时,因为一个月是1到31天(最长),我们通过在数据库中配置客户经理日历的表,其中有
customerid,customercode,no1,no2,no3,no4,no5------,no31,remark,tag,status .......
生成的bean和上面的表的字段相对性,如customerbean
我们通过jdbc从数据库查询得到客户经理每个月的数据,通过画表格的方式生成客户经理月报,输出每天的记录时,调用bean的1-31天的方法,如果不采用reflect那么将会是恼人的代码,采用reflect则会节省很多的时间和空间,
d.最有用的也是最经常使用的,通过回调的方式从resultset中查询数据,查询字段和类型的内容是动态的,查询的sql也是动态的即结果集是动态的。这时我们可以很好的使用反射机制。通过指定的字段和类型,使用反射的方法在结果集中查找,并封装成map传回。
具体实例:如何判断对象是否是个空对象以及是否对其属性使用了set方法 即:Object o = new Object(),没有调用set方法是不行的。
/**
* 读取对象的值
* @param fieldName
* @param o
* @return
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static Object getFieldValueByName(String fieldName, Object o) throws Exception {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(o, new Object[] {});
return value;
}
/**
* 判断一个对象是否只是new了一个空对象
* @param obj
* @return
* @throws Exception
*/
public static boolean judgeObject(Object obj) throws Exception{
Class c = obj.getClass();
Field[] fields = c.getDeclaredFields();
boolean[] arr = new boolean[fields.length-2];
int j = 0;
for(int i = 2; i < fields.length; i++){
String type = fields[i].getType().getName();
String fieldName = fields[i].getName();
if("java.lang.String".equals(type)){
String val = (String)getFieldValueByName(fieldName, obj);
if(verificaton(val)){
arr[j++] = true;
} else {
arr[j++] = false;
}
} else if("java.util.Date".equals(type)){
Date val = (Date)getFieldValueByName(fieldName, obj);
if(verificaton(val)){
arr[j++] = true;
} else{
arr[j++] = false;
}
} else if("int".equals(type)){
int val = (Integer) getFieldValueByName(fieldName, obj);
if(verificaton(val)){
arr[j++] = true;
} else{
arr[j++] = false;
}
} else if("doulbe".equals(type)){
double val = (Double) getFieldValueByName(fieldName, obj);
if(verificaton(val)){
arr[j++] = true;
} else{
arr[j++] = false;
}
} else if("long".equals(type)){
long val = (Long) getFieldValueByName(fieldName, obj);
if(verificaton(val)){
arr[j++] = true;
} else{
arr[j++] = false;
}
} else {
arr[j++] = false;
}
}
int k = 0;
for(int i = 0; i < arr.length;i++){
if(arr[i] != true){
k++;
}
}
if(k == arr.length ) {
return false;
}
else {
return true;
}
}