框架設計之魂——反射

来源:https://www.cnblogs.com/daimenglaoshi/archive/2022/08/17/16596968.html
-Advertisement-
Play Games

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();

                  }

                 

                 

        

         }

  

 

 

 

  1. 根據反射獲取類中所有的欄位

 

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();

              }

      

             

       }

​

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 用的openwrt路由器,家裡寬頻申請了動態公網ip,為了方便把22 80埠映射到公網,發現經常被暴力破解,自己寫了個臨時封禁ip功能的腳本,實現5分鐘內同一個ip登錄密碼錯誤10次就封禁這個ip 5分鐘,並且進行郵件通知 使用步驟 openwrt為19.07.03版本,其他版本沒有測試過 安裝b ...
  • 發現Rocky Linux已經升級了9.0版本,看著自己用著的8.5版本,躍躍欲試,於是就索性升級了。兩者的支持年限沒有太大的差別,先說我的想法:升不升級無所謂。 並不是9.0有什麼特別牛的特性,只是單純的想升級折騰一下而已。 記錄一下自己遷移的過程。 遷移過程 基本的參考都是來自:https:// ...
  • 本課程主要介紹 StoneDB-5.6 在 Ubuntu 20.04 LTS 下的手動編譯,在 CentOS 和 RedHat 的編譯詳見官方文檔。 如果想快速部署,詳見官方文檔 https://stonedb.io/zh/docs/getting-started/quick-deployment ...
  • 發佈和訂閱模式(Pub/Sub)是構建企業級 .NET 應用程式不可或缺的工具。Pub/Sub 是一種消息傳遞範式,消息的發送方(發佈者)不知道目標接收方(訂閱者)的任何信息。此外,發佈者和訂閱者之間不直接發生交互,而是依賴一種叫作主題的公共媒介。因此,這是一個鬆散耦合的消息模型。 現在,我們假設在... ...
  • Oracle 備份與恢復 (Docker部署版) 一,宿主機設置定時備份腳本 1.檢查Oracle容器是否正常運行 docker ps 2.進入容器,創建shell腳本 #oracle11g 是容器名 docker exec -it oracle11g bash #創建資料庫dump的目錄 mkdi ...
  • StoneDB 的整體架構分為三層,分別是應用層、服務層和存儲引擎層。應用層主要負責客戶端的連接管理和許可權驗證;服務層提供了 SQL 介面、查詢緩存、解析器、優化器、執行器等組件;Tianmu 引擎所在的存儲引擎層是 StoneDB 的核心,數據的組織和壓縮、以及基於知識網格的查詢優化均是在 Tia ...
  • 1.概述 說起垃圾收集(Garbage Collection, GC),大部分人都把這項技術當做Java語言的伴生產物。事實上,GC的歷史遠遠比Java久遠,1960年誕生於MIT的Lisp是第一門 真正使用記憶體動態分配和垃圾收集技術的語言。當Lisp還在胚胎時期時,人們就在思考 GC需要完成的三件 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...