javaweb-codereview 學習記錄-4

反射java.lang.Runtime

以前在p牛的知識星球中也學過反射機制調用Runtime來執行命令時須要用getruntime來返回Runtime類的實例,由於Runtime類設計是單例模式,而且該類的構造方法是私有的,所以沒法直接經過newinstance來實例化該類,所以除了經過getRuntime來返回類的實例來調用該類的方法外,還能夠經過反射直接獲取該類的構造方法而且設置訪問屬性來實例化該類。java

import sun.misc.IOUtils;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class reflect_runtime {
    private static Object cmd="calc";

    public static void main (String args[]) throws Exception {
        // 獲取Runtime類對象
        Class runtimeClass1 = Class.forName("java.lang.Runtime");

// 獲取構造方法
        Constructor constructor = runtimeClass1.getDeclaredConstructor();
        constructor.setAccessible(true);

// 建立Runtime類示例,等價於 Runtime rt = new Runtime();
        Object runtimeInstance = constructor.newInstance();

// 獲取Runtime的exec(String cmd)方法
        Method runtimeMethod = runtimeClass1.getMethod("exec", String.class);

// 調用exec方法,等價於 rt.exec(cmd);
        Process process = (Process) runtimeMethod.invoke(runtimeInstance, cmd);



    }

}

上面的代碼註釋已經解釋的很是清楚了,此時能夠經過class類型對象的getDeclaredConstructor()返回類的無參數構造方法,而後再經過setAccessible(true)來修改該構造方法的訪問屬性,從而方便接下來經過該構造器來newInstance該類的實例。數組

 而這裏getRuntime返回的就是該類的實例函數

 

 

getConstructor和getDeclareConstructor均可以得到類的構造方法,區別是後者能夠拿到類的私有構造方法,而前者不行,因此通常來講要拿到類的構造方法都用前者,固然若是一個類有多個構造方法,那麼取其構造方法時能夠加上其方法的入口參數類型,和反射調用函數較爲相似,那麼getDeclareConstructors就能夠得到類的全部的構造函數,返回爲數組,就能夠進行更多操做。spa

反射調用類方法

這一點在p牛的知識星球中也有,經過class類型的對象來調用類的方法,固然這裏也有兩種方式,getMethod和getDeclareMethod都可以獲取到類成員方法,區別在於getMethod只能獲取到當前類和父類的全部有權限的方法(如:public修飾的方法),而getDeclareMethod能獲取到當前類的全部成員方法(不包含父類)。設計

經過Method.invoke()反射調用方法時,invoke函數的第一個參數通常爲反射調用的類的實例,第二個開始即爲傳入的參數,可是若是調用的是類的靜態方法,則第一個參數能夠爲null,由於調用類的靜態方法不須要實例化該類。code

反射調用成員變量

經過getDeclaredField就可以拿到該類全部的成員變量。對象

getFieldgetDeclaredField的區別同getMethodgetDeclaredMethodblog

 獲取成員變量值:get

Object obj = field.get(類實例對象);
修改爲員變量值:
field.set(類實例對象, 修改後的值);

同理這裏修改相似private修飾的變量時也可使用setAccessible來修改訪問權限cmd

相關文章
相關標籤/搜索