JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。 ...
/* *作者:呆萌老師 *☑csdn認證講師 *☑51cto高級講師 *☑騰訊課堂認證講師 *☑網易雲課堂認證講師 *☑華為開發者學堂認證講師 *☑愛奇藝千人名師計劃成員 *在這裡給大家分享技術、知識和生活 *各種乾貨,記得關註哦! *vx:it_daimeng */
反射是框架設計的靈魂
一、什麼是反射
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼文件對應的Class類型的對象.
二、反射的原理
反射就是把java類中的各種成分映射成一個個的Java對象
例如:一個類有:成員變數、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把個個組成部分映射成一個個對象。
其實:一個類中這些成員方法、構造方法、在加入類中都有一個類來描述
三、反射機制主要提供以下功能:
①在運行時判斷任意一個對象所屬的類;
②在運行時構造任意一個類的對象;
③在運行時判斷任意一個類所具有的成員變數和方法;
④在運行時調用任意一個對象的方法;
⑤生成動態代理。
四、Class類
1.獲取Class對象的三種方式
1、Class clazz1 = Class.forName("全限定類名"); //通過Class類中的靜態方法forName,直接獲取到一個類的位元組碼文件對象,此時該類還是源文件階段,並沒有變為位元組碼文件。
2、Class clazz2 = Person.class; //當類被載入成.class文件時,此時Person類變成了.class,在獲取該位元組碼文件對象,也就是獲取自己, 該類處於位元組碼階段。
3、Class clazz3 = p.getClass(); //通過類的實例獲取該類的位元組碼文件對象,該類處於創建對象階段
通過類名獲取Class對象,Class<T> c = Class.forName("類的完全路徑");
通過Class對象獲取具體的類對象:Object o = (Object) c.newInstance();
2、獲取類中的構造方法:
3、獲取類中的屬性:
4、獲取類中的方法:
五、反射的使用
註意:在運行期間,一個類,只有一個Class對象產生。
1.通過反射獲取構造方法並使用
2 .通過反射獲取不同的構造方法。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); //反射用法1 try { Class clazz1=Class.forName("com.test.pojo.Student"); //根據參數列表獲得指定的構造函數 Constructor constructor= clazz1.getDeclaredConstructor(String.class,int.class); //根據構造函數創建對象 Student student=(Student) constructor.newInstance("zhangsan",23); response.getWriter().println(student.getSname()); //獲得所有的構造函數 Constructor[] arr= clazz1.getDeclaredConstructors(); for(Constructor constructor2 : arr) { //獲得構造函數的參數類型 Class[] brr= constructor2.getParameterTypes(); for(Class clazz2:brr) response.getWriter().print(clazz2.getName()+","); response.getWriter().println(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); try { Class clazz=Class.forName("com.test.pojo.Student"); //獲得student類中所有定義的屬性(每個屬性組裝成了一個對象) Field[] arr=clazz.getDeclaredFields(); for(Field field: arr) { response.getWriter().println(Modifier.toString(field.getModifiers())+","+field.getName()+","+field.getType()); } //根據名稱找到指定的欄位 Field field=clazz.getDeclaredField("sid"); Student student=(Student) clazz.newInstance(); field.setAccessible(true); field.set(student, 1); response.getWriter().println(student.getSid()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
4、通過反射獲取方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); Class clazz=Student.class; Student student=new Student(); try { //通過反射 獲得指定的方法 Method method= clazz.getDeclaredMethod("test", String.class,int.class); //調用改方法 method.invoke(student, "zhangsan",23); Method method2=clazz.getDeclaredMethod("test", int.class); Object o=method2.invoke(student, 25); System.out.println(o.toString()); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } }