反射機制是什麼
反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態擷取的資訊以及動態調用對象的方法的功能稱為java語言的反射機制。
** 反射機制能做什麼
**
反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類; 在運行時構造任意一個類的對象; 在運行時判斷任意一個類所具有的成員變數和方法; 在運行時調用任意一個對象的方法; 產生動態代理。
反射機制擷取類有三種方法,我們來擷取Employee類型
//第一種方式: Classc1 = Class.forName("Employee"); //第二種方式: //java中每個類型都有class 屬性. Classc2 = Employee.class; //第三種方式: //java語言中任何一個java對象都有getClass 方法 Employeee = new Employee(); Classc3 = e.getClass(); //c3是運行時類 (e的運行時類是Employee)
擷取方法,和構造方法,不再詳細描述,只來看一下關鍵字: getDeclaredMethods() 擷取所有的方法 getReturnType() 獲得方法的放回類型 getParameterTypes() 獲得方法的傳入參數類型 getDeclaredMethod(“方法名”,參數類型.class,……) 獲得特定的方法 getDeclaredConstructors() 擷取所有的構造方法 getDeclaredConstructor(參數類型.class,……) 擷取特定的構造方法
另外:getDeclaredFields()獲得某個類的所有申明的欄位,即包括public、private和proteced,但是不包括父類的申明欄位。
getFields()獲得某個類的所有的公用(public)的欄位,包括父類。
下面是舉例使用:
package com.app;public class T1 { public static void main(String[] args) { try { //建立類 Class<?> class1 = Class.forName("com.app.Person");; //建立執行個體化:相當於 new 了一個對象 Object object = class1.newInstance() ; //向下轉型 Person person = (Person) object ; person.setId( "100"); person.setName( "jack") ; System.out.println( "id: " + person.getId() + " name: " + person.getName() ); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}
運行結果:
id: 100 name: jack
執行個體二:
package com.app;import java.lang.reflect.Field;public class T1 { public static void main(String[] args) { try { //建立類 Class<?> class1 = Class.forName("com.app.Person"); //建立執行個體 Object person = class1.newInstance(); //獲得id 屬性 Field idField = class1.getDeclaredField( "id" ) ; //打破封裝 實際上setAccessible是啟用和禁用訪問安全檢查的開關,並不是為true就能訪問為false就不能訪問 //由於JDK的安全檢查耗時較多.所以通過setAccessible(true)的方式關閉安全檢查就可以達到提升反射速度的目的 idField.setAccessible( true ); //給id 屬性賦值 idField.set( person , "100") ; //列印 person 的屬性值 System.out.println( idField.get( person )); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
運行結果
100
另外說一下Class類提供了四個public方法,用於擷取某個類的構造方法。
Constructor getConstructor(Class[] params) 根據建構函式的參數,返回一個具體的具有public屬性的建構函式Constructor getConstructors() 返回所有具有public屬性的建構函式數組Constructor getDeclaredConstructor(Class[] params) 根據建構函式的參數,返回一個具體的建構函式(不分public和非public屬性)Constructor getDeclaredConstructors() 返回該類中所有的建構函式數組(不分public和非public屬性)
四種擷取成員方法的方法
Method getMethod(String name, Class[] params) 根據方法名和參數,返回一個具體的具有public屬性的方法Method[] getMethods() 返回所有具有public屬性的方法數組Method getDeclaredMethod(String name, Class[] params) 根據方法名和參數,返回一個具體的方法(不分public和非public屬性)Method[] getDeclaredMethods() 返回該類中的所有的方法數組(不分public和非public屬性)
四種擷取成員屬性的方法
Field getField(String name) 根據變數名,返回一個具體的具有public屬性的成員變數Field[] getFields() 返回具有public屬性的成員變數的數組Field getDeclaredField(String name) 根據變數名,返回一個成員變數(不分public和非public屬性)Field[] getDelcaredField() 返回所有成員變數組成的數組(不分public和非public屬性)