1. 程式人生 > 其它 >java程式碼學習(二)——java反射機制

java程式碼學習(二)——java反射機制

Java反射機制

Java反射機制的核心是在程式執行時動態載入類並獲取類的詳細資訊,從而操作類或物件的屬性和方法。本質是JVM得到class物件之後,再通過class物件進行反編譯,從而獲取物件的各種資訊。

而在一個物件或者方法的作用域defaultprivate時,我們是無法進行直接的呼叫的,這時候就需要用到java的反射機制了。

java的反射機制總共有4個呼叫方式,分別是Class.forName方法、new呼叫、.class呼叫和getClass方法。然而通過實測只有forName能呼叫ProcessImpl類。

//第一種方法,使用class.forName進行呼叫
Class<?> clazz1 = Class.forName("java.lang.ProcessBuilder");
//第二種方法,

new一個要呼叫的類的物件
ProcessBuilder clazz2 = new ProcessBuilder();
//第三種方法,需要呼叫的類名加上.Class
Class<ProcessBuilder> clazz3 = ProcessBuilder.class;
//第四種方法,定義字串呼叫需要的類,使用getClass獲取該類
String str = "java.lang.ProcessBuilder";
Class clazz = str.getClass();

在上一篇文章中,由於ProcessImpl無法直接呼叫,所以使用了java的反射機制來呼叫。而呼叫還需要一些步驟。因為forName

只是獲取了這個類,後面是通過Method類來獲取需呼叫的方法。getDeclaredMethod是從當前類所有宣告的方法中獲取方法,不包括父類宣告的方法,而getMethod函式是從public方法中獲取方法,顯然不適用。最後通過invoke呼叫start方法。

public class ProcesslmplTest {
public static void main(String []args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException{
Class clazz = Class.forName("java.lang.ProcessImpl"); // 獲取

ProcessImplClass物件
Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class); // 獲取start方法物件
method.setAccessible(true); // 設定方法允許在當前程式碼使用
Process p = (Process) method.invoke(null, new String[]{"cmd.exe","/c","calc.exe"}, null, ".", null, true); // 呼叫start方法
System.out.println(p);
}
}

Java反射相關操作

Java反射時使用了forName來獲取類,我們可以通過這個類來獲取類的方法等:

  • 獲取成員方法Method
  • 獲取成員變數Field
  • 獲取建構函式Constructor

獲取成員方法資訊

public Method getDeclaredMethod(String name, Class<?>... parameterTypes) // 得到該類所有的方法,不包括父類的
public Method getMethod(String name, Class<?>... parameterTypes) // 得到該類所有的public方法,包括父類的

即前面使用到的getDeclaredMethod方法。還可以通過Method[]來迴圈查詢類的所有方法。

獲取成員變數資訊

public Field getDeclaredField(String name) // 獲得該類自身宣告的所有變數,不包括其父類的變數
public Field getField(String name) // 獲得該類自所有的public成員變數,包括其父類變數

獲取建構函式

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) // 獲得該類所有的構造器,不包括其父類的構造器
public Constructor<T> getConstructor(Class<?>... parameterTypes) // 獲得該類所以public構造器,包括父類

瞭解了這些也算是對java反射機制有了初步的認識了。