JAVA基礎--Class反射的簡單應用(2)

上章瞭解了Class的做用,那麼,此次咱們來看看反射究竟是怎麼回事:java

package reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


/**
 *@description TODO 反射測試類
 *@date  2018年1月1日
 *@author  geYang
 **/
public class ClassTest2 {
    /**
     * 反射賦值: 
     *   Java反射機制是在運行狀態中,對於任意一個類,都可以知道這一個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;
     * 這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制;
     * 
     * @throws Exception 
     **/
    public static void main(String[] args) throws Exception {
        //1,獲取類:
        Class<?> clazz = Class.forName("entity.Person");
        System.out.println("類:"+clazz);
        
        //2,獲取Person類的默認構造器:
        Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{});
        System.out.println("默認構造器:"+constructor);
        
        //3,利用默認構造器獲取對象:
        Object object = constructor.newInstance(new Object[]{});
        System.out.println("對象:"+object);
        
        //4,獲取類下的全部方法:
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods){
            //獲取方法名:
            String methodName = method.getName();
            //判斷是否爲以set開頭的方法:
            if(methodName.startsWith("set")){
                //經過截取字符傳的方式來拿到屬性名:
                String fieldName = methodName.substring(3);
                fieldName = fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1);
                //得到屬性:
                Field field = clazz.getDeclaredField(fieldName);
                //得到屬性的具體類型:
                Class<?> type = field.getType();
                //若是類型爲int類型:
                if(type==int.class){
                    //反射調用set方法
                    method.invoke(object, new Object[]{18});
                }
                if(type==String.class){
                    if("name".equals(fieldName)){
                        method.invoke(object, new Object[]{"張三"});
                    }
                    if("address".equals(fieldName)){
                        method.invoke(object, new Object[]{"綿陽"});
                    }
                }
            }
        }
        System.out.println("對象:"+object);
        
        /**
         * Method 反射調用自身:
         *  method.invoke(object, new Object[]{"張三"});
         *  對帶有指定參數的指定對象調用,由此Method對象表示底層方法.
         *  注: 1:若是底層方法是實例方法,第一個參數就是該對象的實例,第二個參數就是方法的參數列表,invoke的返回值就是實例方法的返回值;
         *  2: 若是底層方法是靜態方法,那麼能夠忽略實例參數,該參數可爲null;
         *  3: 若是底層方法所需的形參數爲0(無參),則參數列表可爲  null<===>new Object[]{}(推薦使用new Object[]{});
         *  例:
         * */
        Method method = clazz.getDeclaredMethod("printInfo", new Class[]{});
        //靜態方法,實例可爲null;無參,參數可爲null;
        Object invoke = method.invoke(null, new Object[]{});
        System.out.println(invoke);
        
        /**
         * 暴力反射
         * */
        Field field = clazz.getDeclaredField("name");
        //破壞屬性私有化
        field.setAccessible(true);
        field.set(object, "李四");
        System.out.println(object);
    }
    
}

初次聽到反射,咱們都會以爲比較深奧,其實用法就是這麼簡單,但至於怎麼用就要看各自功力的深厚啦;測試

參考: https://ke.qq.com/course/180327flex

相關文章
相關標籤/搜索