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;
}
}