ClassLoader getClassLoader()
返回该类的类加载器。
- 获取Field(属性)----->包含属性的修饰符,类型及名称 如:[private int age];
Field
getDeclaredField(String name)
返回一个Field
对象,该对象反映此Class
对象所表示的类或接口的指定已声明字段。Field[]
getDeclaredFields()
返回Field
对象的一个数组,这些对象反映此Class
对象所表示的类或接口所声明的所有字段 - 获取Method(普通方法)----->包含方法的修饰符,返回值类型,方法名称及抛出的异常 如:[public string getName()];
Method
getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方
Method[]
getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
- 获取Constructor(构造方法)----->包含构造方法的修饰符,方法名称及抛出的异常 如:[public Student()];
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个Constructor
对象,该对象反映此Class
对象所表示的类或接口的指定构造方法。Constructor<?>[] getDeclaredConstructors()
返回Constructor
对象的一个数组,这些对象反映此Class
对象表示的类声明的所有构造方法。
例如:(claz是相关类的字节码对象的引用)
Constructor[] cons = claz.getConstructors();//claz.getConstructors()获取的是类中的所有的公开的构造方法
setAccessible(boolean flag) | 将此对象的 accessible 标志设置为指示的布尔值。 |
public class ReflectUtil {
/**
* 过程: 前台数据------>后台实体类对象
* 功能:将【添加页面】发送的请求保存到对应的实体类对象中
* @param req 包含本次请求包含的请求参数
* @param classObj 与当前【添加页面】对应的【实体类文件】
* @return
*/
public static Object parseRequest(HttpServletRequest req,Class classObj)throws Exception{
//1. 根据获得【class文件】,创建一个【实例对象】
Object obj= classObj.newInstance();
//2. 获得本次请求,涉及的所有的【请求参数名称】
Enumeration paramArray= req.getParameterNames();
// 3. 循环遍历【枚举】
while(paramArray.hasMoreElements()){
// 3.1 每一次循环,从【枚举】中获得一个【请求参数名称】 sid
String paramName= (String) paramArray.nextElement();
//3.2 到【class文件】寻找与当前【请求参数名称】相同的【同名属性对象】
//Field fieldObj=classObj.getDeclaredField(paramName);
//表单域中有可能存在非实体类中的属性,所以采用以下方式
Field fieldObj =null;
try{
fieldObj=classObj.getDeclaredField(paramName);
}catch(NoSuchFieldException ex){
System.out.println("属性"+paramName+"在当前类 "+classObj.getName()+"不存在");
continue;
}
fieldObj.setAccessible(true);
// 3.3 读取【请求参数】包含的【内容】
String value = req.getParameter(paramName);
//3.4 读取【同名属性对象】的【数据类型名称】
String typeName=fieldObj.getType().getName();//[int,double,String ,java.util.Date,boolean]
//3.5 根据【同名属性对象】的【数据类型名称】对【请求参数】包含的【内容】进行【类型转换】
Object data=convertType(typeName,value);
// 3.6 将转换后的数据赋值给【同名属性对象】
fieldObj.set(obj, data);//通知JVM,强制为当前【实例对象】中指定的【属性】进行赋值。
}
//4. 返回赋值好的【实例对象】
return obj;
}
实例二:模拟数据库数据转换为实体类
/**
* 过程: 数据库数据------>后台实体类对象
* 功能:resultSet -----> List
* @param rs
* @param xmlPath
* @return
*/
public static List convert(ResultSet rs,String xmlPath)throws Exception{
//0.局部变量
List list = new ArrayList();
// 1.将硬盘上【实体类映射文件】加载到内存
InputStream in = new FileInputStream(xmlPath);
SAXReader saxObj = new SAXReader();
Document xmlObj = saxObj.read(in);
//2.获得【临时表】包含【内部结构】
ResultSetMetaData rsmd= rs.getMetaData();
//3.从【实体类映射文件】获得与当前【临时表】对应【实体类文件】
String xPath="//@class";
Attribute attrObj= (Attribute) xmlObj.selectSingleNode(xPath);
String classPath =attrObj.getValue();
Class classObj=Class.forName(classPath);
// 4.循环【临时表数据行】
while(rs.next()){
//4.1,每次循环时,生成一个【实例对象】
Object obj = classObj.newInstance();
//4.2 循环【当前数据行】中的字段信息
for(int col=1;col<=rsmd.getColumnCount();col++){
//4.2.1 每次循环,获得【当前数据行】中一个【字段名称】
String colName = rsmd.getColumnName(col); //DEPTNO
//4.2.2 到 【实体类映射文件】寻找与【字段名称】对应【属性名】
xPath="//property[@colName='"+colName+"']";
Element property= (Element) xmlObj.selectSingleNode(xPath);
String fieldName= property.attributeValue("name"); //departId
//4.2.3 到 【实体类文件】寻找对应的【属性对象】
Field fieldObj=classObj.getDeclaredField(fieldName);// private int departId;
fieldObj.setAccessible(true);
//4.2.4 读取【当前数据行】,这个【字段名称】关联的数据
String value = rs.getString(colName);
// 4.2.5 根据【属性对象】的数据类型名称,对取得字段内容进行类型转换
String typeName=fieldObj.getType().getName();
Object data=convertType(typeName,value);
// 4.2.6 将转换后的数据添加到【属性对象】 属性对象.set(【实例对象】,data)
fieldObj.set(obj, data);
}
//4.3 将赋值好的 【实例对象】保存到list
list.add(obj);
}
//5.将list返回
return list;
}
//公用的判断数据类型并转换的方法
private static Object convertType(String typeName,String value)throws Exception{
Object data =null;//保存类型转换后的数据
if("int".equals(typeName)){
data = Integer.valueOf(value);
}else if("double".equals(typeName)){
data = Double.valueOf(value);
}else if("boolean".equals(typeName)){ // "false" "true"
data = Boolean.valueOf(value);
}else if("java.util.Date".equals(typeName)){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
data=sdf.parse(value);
}else if("java.lang.String".equals(typeName)){
data = value;
}
return data;
}
}