Java 反射機制(Reflect)允許程序在運行時加載、探知、使用編譯期間徹底未知的 class,核心類 java.lang.Class。java
經過把指定類中各類元素映射成 java.lang.reflect 反射包中的相應類,使得咱們能夠動態的調用類成員.好比構造方法、成員方法、成員變量等。數據庫
Java 內省機制(IntroSpector)是對 JavaBean 屬性、事件的一種默認處理方法,核心類 java.beans.BeanInfo。apache
經過 java.beans 包下一套 API 來訪問 javaBean 的 getter/setter方法。spa
//JDK 反射API public static Class<?> forName(String className) //經過配置靈活加載不一樣數據庫驅動 Class.forName(driver);
運行時獲取任意類的成員方法:3d
Class<String> stringClass = String.class; //獲取聲明的全部方法(不包括繼承方法) Method[] methods = stringClass.getDeclaredMethods(); //獲取全部方法 Method[] methods1 = stringClass.getMethods(); //獲取特定方法 Method indexOf = stringClass.getMethod("indexOf", int.class);
運行時獲取任意類的成員變量:code
//獲取全部類屬性 Field[] fields = stringClass.getFields(); //獲取聲明的全部成員屬性(不包括繼承屬性) Field[] declaredFields = stringClass.getDeclaredFields(); //獲取特定字段 Field hashField = stringClass.getDeclaredField("hash");
運行時調用任意類的方法:對象
Constructor<String> constructor = stringClass.getConstructor(String.class); String newInstance = constructor.newInstance("orson"); Object invoke = indexOf2.invoke(newInstance, "n");
在運行時實例化對象並訪問對應字段比直接 new 一個對象來操做到底有什麼好處?blog
最主要的是提升靈活性和可擴展性, Spring 託管類、Struts 請求映射 Action、Hibernate 填充實體屬性這些過程,反編譯源碼你都會看到反射。繼承
經過修改配置中類文件的「描述」,不須要修改代碼和編譯,進行動態有必要的加載。接口
內省基於反射實現,主要是來簡化 JavaBean 的賦值與取值,若是你使用過 Struts 表單到後臺 Action 字段填充核心就是內省。
UserDTO userDTO = new UserDTO(); //內省使用 setter 方法設置特定 javaBean 屬性 PropertyDescriptor userName = new PropertyDescriptor("userName", UserDTO.class); Method writeMethod = userName.getWriteMethod(); writeMethod.invoke(userDTO,"userA"); //內省使用 getter 方法獲取特定 javaBean 屬性 Method method = userName.getReadMethod() ; Object result = method.invoke(userDTO) ;
不少開源項目都對 JDK 底層反射和內省進行了封裝,提供了簡潔的 API 接口方便使用,如 apache-common、hutool等,這裏就不贅述了。