通過java反射機制操作物件的屬性方法
阿新 • • 發佈:2019-01-22
- 獲得物件的類屬性(Class 類)
- Class 類名.class
- Class 物件名.getClass()
- Class Class.forName(類的具體名稱);
- 通過類獲得屬性Field(Field類)
- Field getField(String name);獲得指定名字的公共屬性
- Field[] getFields();獲得全部公共屬性(包括繼承父類,實現介面)
- Field getDclaredField(String name);獲得指定名字的屬性
- Field[] getDeclaredFields();獲得當前類的全部屬性
- 對屬性進行get和set操作
- 首先需要對屬性的訪問許可權進行設定
- setAccessable(true);設定為可訪問的
- setAccessable(true);設定為可訪問的
- Field常用的方法
- String getName();獲得當前屬性的名稱
- Class<?> getType();獲得但當前屬性對應的型別
- int getModifiers();獲得訪問修飾符對應的整數
- void set(Object obj,Object value);將指定物件obj的屬性修改為新的值value(相當於 物件名.屬性名=vlaue或者 物件名.setXXX(value))
- 如果知道具體的屬性型別,可以通過setInt() setFloat()直接賦值(沒有setString()方法)
- Object get(Object obj); 返回指定物件上此
Field
表示的欄位的值 - 知道具體型別可以getChar() getInt() getBoolean() 等
- 例子:
- VO類
import java.util.Date; public class Student { private int stuid=1; private String name="張飛"; private String sex="男"; private String type="坦克"; Date birth; public Student() { super(); } public int getStuid() { return stuid; } public void setStuid(int stuid) { this.stuid = stuid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
測試類
import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Date; import com.oracle.vo.Student; public class Test { public static void main(String[] args) throws Exception { Student s=new Student(); Class<?> c=s.getClass(); //獲得屬性 Field f=c.getDeclaredField("name"); //設定訪問許可權,對非public屬性進行操作 f.setAccessible(true); //賦值 f.set(s,"齊天大聖"); Field f1=c.getDeclaredField("birth"); //設定訪問許可權,對非public屬性進行操作 f1.setAccessible(true); //賦值 f1.set(s,new Date()); System.out.println(f.get(s)); Field[] fs=c.getDeclaredFields(); for(int i=0;i<fs.length;i++) { fs[i].setAccessible(true); Object val=fs[i].get(s); System.out.println(val); } }
輸出結果:
齊天大聖 1 齊天大聖 男 坦克 Sat Nov 04 21:00:35 CST 2017
- 通過對屬性值的操作可以生成完整的sql語句
/** * 執行資料庫的插入操作 * @param obj */ public void insert(Object obj) { Class<?> c=obj.getClass(); Field[] fs=c.getDeclaredFields(); StringBuffer sql=new StringBuffer(); StringBuffer sql_val=new StringBuffer(); sql.append("insert into "+c.getSimpleName()+" ("); sql_val.append(" values("); for(int i=0;i<fs.length;i++) { fs[i].setAccessible(true); if(i!=fs.length-1) { sql.append(fs[i].getName()+","); sql_val.append("?,"); }else { sql.append(fs[i].getName()+")"); sql_val.append("?)"); } } System.out.println("*****"+sql.append(sql_val)+"*****"); //獲得連線,建立宣告 Connection conn=getConnection(); PreparedStatement ps=null; try { ps=conn.prepareStatement(sql.toString()); //設定引數 for(int i=0;i<fs.length;i++) { fs[i].setAccessible(true); //System.out.println(fs[i].get(obj)); ps.setObject(i+1, fs[i].get(obj)); } //執行插入語句 ps.execute(); System.out.println("插入操作執行成功"); }catch(Exception e) { e.printStackTrace(); }finally { close(ps); close(conn); } }
- 首先需要對屬性的訪問許可權進行設定
- 對構造方法操作(Constructor類)
- Constructor代表類中的一個構造方法,這個類中封裝了構造方法的定義
(訪問修飾符,方法名,引數列表) - 常用的方法
- String getName();獲得方法名
- int getModifiers();獲得訪問修飾符
- Class[] getParameterTypes();獲得構造方法的引數型別
- newInstance(Object...args)使用當前的的構造方法建立一個物件
- 獲得Constructor
- getConstructor(Class...c)獲得某個公共的構造方法,
- Class[] getConstructors();獲得所有的構造方法
- getDeclaredConstructor(Class...c);獲得某個構造方法
- Class[] getDeclaredConstructors();獲得所有的構造方法
- 根據無參的構造方法建立例項可以直接呼叫Class類的newInstance()方法
- 結合Field對屬性的get,set方法以及構造方法對資料庫檔案進行查詢
/** * 查詢所有記錄 * @param c * @return */ public <T> List<T> getAll(Class<T> c){ List<T> list=new ArrayList<T>(); Connection conn=getConnection(); Field[] f=c.getDeclaredFields(); PreparedStatement ps=null; ResultSet rs=null; try { ps=conn.prepareStatement("select * from "+c.getSimpleName()); rs=ps.executeQuery(); while(rs.next()) { //呼叫無參的構造方法建立一個物件 T t=c.newInstance(); for(Field fs:f) { //設定訪問許可權 fs.setAccessible(true); //為t的每一個屬性賦值(根據屬性名稱獲得value,然後在通過set方法賦值給新的例項化物件) fs.set(t, rs.getObject(fs.getName())); } //將每一個物件資料儲存到List中 list.add(t); } }catch(Exception e) { e.printStackTrace(); }finally { close(rs); close(ps); close(conn); } return list; }
- 對普通方法的操作(Method類)
-
Method
提供關於類或介面上單獨某個方法(以及如何訪問該方法)的資訊。所反映的方法可能是類方法或例項方法(包括抽象方法)。
(JDK API1.6)Method
允許在匹配要呼叫的實參與底層方法的形參時進行擴充套件轉換;但如果要進行收縮轉換,則會丟擲IllegalArgumentException
。 - 簡單來說:Method類代表類方法的定義,包括方法的訪問修飾符,返回值,名稱,引數型別
- 常用的方法
- String getName();獲得方法名
- int getModifiers();獲得修飾符
- Class getReturnType();獲得返回值的型別
- Class[] getParameterTypes();獲得引數型別的陣列
- Object invoke(Object obj,Object...args);呼叫obj物件的指定引數列表的方法
- String getName();獲得方法名
- 獲得Method(全部為Class類的方法)
- Method getMethod(String name,Class...args):根據名稱和引數獲得對應的公共方法
- Method[] getMethods():獲得所有公共的方法
- Method getDeclaredMethod(String name,Class...args):根據名稱和引數獲得對應的方法
- Method[] getDeclaredMethods():獲得當前類中定義的所有方法
- 例如獲得java.util.Date的所有方法
//獲得Date的class Class<?> c=Date.class; //獲得Date的所有方法 Method[] m2=c.getDeclaredMethods(); for (Method method : m2) { //獲得返回值型別,訪問修飾符,方法名 System.out.println(method.getReturnType()+"\t"+Modifier.toString(method.getModifiers())+"\t"+method.getName()); //獲得引數列表 Class<?>[] cc=method.getParameterTypes(); for (Class<?> cs : cc) { System.out.println(cs.getSimpleName()); } System.out.println("----------------------------------"); }
- 執行結果
boolean public after Date ---------------------------------- boolean public before Date ---------------------------------- boolean public equals Object ---------------------------------- class java.lang.String public toString ---------------------------------- int public hashCode ---------------------------------- class java.lang.Object public clone ---------------------------------- int public compareTo Date ---------------------------------- int public volatile compareTo Object ---------------------------------- void private readObject ObjectInputStream ---------------------------------- long public static parse String ---------------------------------- long public static UTC int int int int int int ----------------------------- 等。。。。。。。
-
- Constructor代表類中的一個構造方法,這個類中封裝了構造方法的定義