上一篇介紹了java反射的基本概念,並通過一個簡單的例子展示瞭如何獲取一個類所定義的變量和方法
下面將介紹如何通過反射來訪問類裏面的方法,先看一個例子
- importjava.lang.reflect.AccessibleObject;
- importjava.lang.reflect.Field;
- importjava.lang.reflect.Method;
- publicclassTest{
- privateStringname;
- publicStringgetName(){
- returnname;
- }
- publicvoidsetName(Stringname){
- this.name=name;
- System.out.println("初始化name屬性:"+name);
- }
- publicstaticvoidmain(String[]args){
- System.out.println("show方法的輸出:");
- show(newTest());
- System.out.println("getSetMethod方法的輸出:");
- getSetMethod(newTest());
- }
- @SuppressWarnings("unchecked")
- publicstaticvoidshow(Objectclazz){
- try{
- /**
- *獲取類裏面的setName方法並指定其參數是String類型
- */
- MethodsetName=clazz.getClass().getMethod("setName",newClass[]{String.class});
- /**
- *調用setName方法,並指定參數爲"zhjb"
- */
- setName.invoke(clazz,"zhjb");
- /**
- *獲取類裏面的getName方法
- */
- MethodgetName=clazz.getClass().getMethod("getName");
- /**
- *調用getName方法,並打印其返回值
- */
- System.out.println(getName.invoke(clazz));
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- @SuppressWarnings("unchecked")
- publicstaticvoidgetSetMethod(Objectclazz){
- try{
- /**
- *得到定義的變量
- */
- Field[]field=clazz.getClass().getDeclaredFields();
- /**
- *設置訪問權限,即使是private也能訪問
- */
- AccessibleObject.setAccessible(field,true);
- /**
- *給該變量賦值
- */
- field[0].set(clazz,"zhjb");
- System.out.println(field[0].get(clazz));
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }
運行上面的代碼輸出結果爲:
show方法的輸出:
初始化name屬性:zhjb
zhjb
getSetMethod方法的輸出:
zhjb
由輸出的結果可以看出,show方法裏面通過調用類裏面的set方法給變量name賦值,而getSetMethod方法裏面是直接對類裏面成員變量賦值,應爲AccessibleObject.setAccessible(field,true);這樣設置了訪問權限,那麼即使是private也能進行直接的賦值,但是這種方法並不是很好,破壞了JavaBean的規則,所以建議使用通過get 、set的方法來訪問Java類。上面的例子都寫了註釋了,就不在細說了。
下面看一個例子,就是把request裏面的參數根據名字封裝到一個JavaBean裏面
- /**
- *把request對象裏面的屬性拷貝到一個標準的JavaBean裏面,時間格式默認爲yyyy-MM-ddHH:mm:SS
- *因爲只是介紹反射的用法,所以本方法只是做演示,肯定有很多的BUG,Object裏面的屬性沒有自己定義的類
- *如果實際工程中可以使用org.apache.commons.beanutils.BeanUtils.copyProperties()方法
- *@paramobj
- *@paramrequest
- *@throwsParseException
- */
- @SuppressWarnings("unchecked")
- publicstaticvoidcopyProperties(Objectobj,HttpServletRequestrequest)throwsException{
- /**
- *得到定義的變量
- */
- Field[]field=obj.getClass().getDeclaredFields();
- Class[]clazz=newClass[1];
- for(Fieldf:field){
- Objectvalue=request.getParameter(f.getName());
- if(value==null){
- continue;
- }
- StringmethodName=getMethodName(f.getName());
- if(f.getType().getName().equals("java.util.Date")){
- SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-ddHH:mm:SS");
- value=sf.parse(value.toString());
- clazz[0]=Date.class;
- }elseif(f.getType().getName().equals(Integer.class.getName())){
- clazz[0]=Integer.class;
- value=newInteger(value.toString());
- }elseif(f.getType().getName().equals(String.class.getName())){
- clazz[0]=String.class;
- }
- Methodmethod=obj.getClass().getDeclaredMethod(methodName,clazz);
- method.invoke(obj,value);
- }
- }
- /**
- *把屬性的第一個字母變爲大寫,然後在前面加上set,給該屬性賦值,這是JavaBean的標準命名規則
- *@paramfieldName
- */
- publicstaticStringgetMethodName(StringfieldName){
- charc=fieldName.charAt(0);
- if(c>='a'&&c<='z'){
- c=(char)(c-'a'+'A');
- }
- return"set"+c+fieldName.substring(1);
- }
注:Java裏面的屬性必須是對象,有代碼就可以去看如何實現了