Java 反射
难得项目中有点技术的地方,写了大半年的js,要吐了。难得有些我觉得对我有用的地方,记录一下。
内省和反射的区别
反射式在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性
在Java内省中,用到的基本上就是上述几个类。
通过BeanInfo这个类就可以获取到类中的方法和属性,具体的可以参考JDK文档
根据类的变量名来获取类对象的get方法
下面这段是网上的
package com.query;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class BeanInfoUtil {
//这是用来更改类里面的信息的
public static void setProperty(UserInfo userInfo,String userName)throws Exception{
PropertyDescriptor propDesc=new PropertyDescriptor(userName,UserInfo.class);
Method methodSetUserName=propDesc.getWriteMethod();
methodSetUserName.invoke(userInfo, "wong");
System.out.println("set userName:"+userInfo.getUserName());
}
//这是根据变量名获取类信息的
public static void getProperty(UserInfo userInfo,String userName)throws Exception{
PropertyDescriptor proDescriptor =new PropertyDescriptor(userName,UserInfo.class);
Method methodGetUserName=proDescriptor.getReadMethod();
Object objUserName=methodGetUserName.invoke(userInfo);
System.out.println("get userName:"+objUserName.toString());
}
}
PropertyDescriptor类
PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
1、getPropertyType(),获得属性的Class对象。
2、getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法。
3、hashCode(),获取对象的哈希值。
4、setReadMethod(Method readMethod),设置用于读取属性值的方法;setWriteMethod(MethodwriteMethod),设置用于写入属性值的方法;
导包java.bean.*;
然后是自己的程序
首先是获取到类中的变量名,想利用这个变量名去得到get方法的值最初使用了个最笨的方法。拿到变量名,首字母大写后拼接出一个getName().拿到了get方法的名字,然后利用method方法反射。但后来看到了Introspector源码里面也是根据开始的字符串是不是get,set什么的识别的。。
ReportInfo report = reportService.getReport(reportId);
Class<?> reportInfo = ReportInfo.class;
try {
Method m2 = reportInfo.getMethod(tempNew);//tempNew为getName()名字
String name = m2.invoke(report).toString();
System.out.println(name);//这里的name 就是实际获取到的对象的name的值
} catch (Exception e) {
e.printStackTrace();
}
后来发现可以直接根据变量名进行操作
PropertyDescriptor pd = new PropertyDescriptor(tempparment,report.getClass());
//tempparment为变量名
Method m2 = pd.getReadMethod();//Read对应get()方法
String name = m2.invoke(report).toString();
使用内省的方法获取所有的
BeanInfo beanInfo = Introspector.getBeanInfo(ReportInfo.class);
for (PropertyDescriptor p :beanInfo.getPropertyDescriptors()) {
System.out.println(p.getReadMethod().invoke(report,tempparment));
}
或者这样
BeanInfo beninfo = Introspector.getBeanInfo(ReportInfo.class);
//获得所有的属性描述
PropertyDescriptor [] propertydescriptors = beninfo.getPropertyDescriptors();
for(PropertyDescriptor pd:propertydescriptors){
//获得读写方法
System.out.println(pd.getName());
System.out.println(pd.getReadMethod().getName());//读
System.out.println(pd.getWriteMethod().getName());//写
}