后端框架(2):Java的反射機制

什么是java反射機制?

? 回顧之前java程序如何使用類

? ? 1.分析,確定類名,屬性名,方法......創建類

? ? 2.創建類的對象

? ? 3.使用

一切都是已知的。

在程序開發中,在哪兒需要使用哪個類的對象,就在那兒創建這個類對象,去使用即可

這種寫法對于業務開發來說是沒問題的。

但~是!,在一些組件 或者 在框架的開發中,他們本身時不知道要處理哪些類

例如:jackson組件,我們給他什么類,他們就處理轉換什么類

new ObjectMapper().writeValueAsString(result) 

在web.xml中配置了哪些servlet類,tomcat就要創建哪些類對象

<servlet-class>com.skw.dorm.web.LoginServlet</servlet-class><servlet-class>com.skw.dorm.web.TestServlet</servlet-class>

在mybatis中,給了什么類型,mybatis就可以將結果封裝映射到給定的類的對象中

<select id="findAdminById" parameterType="int" resultType="Admin">

等等一系列,這樣單一對著一個明確的類去使用。

問題:如果僅僅知道一個類的類名,能否動態得到類的定義信息,包括哪些方法, 屬性等?

以前已知類名的使用方式,可以看做是正向使用類。

而框架需要只寫一套程序,就可以處理我們給他的任意類

框架需要對任意類處理時,只是知道類的名字,通過類的名字動態才去獲取類中的信息。

把這種對類的使用方式,稱為反向使用。也可以被稱為:反射!

反射

? 概念:

? ? Java反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取信息以及動態調用對象的方法的功能稱為java語言的反射機制。

? ? Java反射機制的作用就是:可動態的獲取類的信息

? 要如何去實現Java的反射機制呢?

? ? 首先了解Java反射相關的API:

????????Java反射相關的類主要包括

? ? ? ? ????????Class 類型

????????????????Constructor 構造方法

????????????????Method 方法

????????????????Field 屬性

????????除了Class外,其他類都位于java.lang.reflect包中

????????可見,反射API將類的類型、方法、屬性都封裝成了類,其中最重要的類是 Class,可以說,反射的使用都是從Class開始。

? ? 1、Class類

????????java.lang.Class

????????一旦class文件被加載到內存,就會為其創建一個Class對象。任何類被使用時都會創建一個Class對象。

????????Class類是Java反射機制的基礎,通過Class類,可以得到一個類的基本信息。

Class類的對象,表示當前正在運行中的類和接口。

獲得Class的三種方法

要使用Class類的方法,必須先獲得該類的Class類的實例,獲得Class 類實例的常用方法有如下三種

//方式1:通過類的名稱(包名+類名)來獲取Class類Class clazz1 = Class.forName(classname);System.out.println(clazz1);
//方式2:通過只知道類來獲取Class類Class clazz2 = User.class;
 //方式3:通過知道類的對象來獲取Class類User user = new User();Class clazz3 = user.getClass();
Class類的常用方法
方法名功能說明
static Class forName(String name)返回指定類名?name?的?Class?對象
Object newInstance()調用缺省構造函數,返回該Class對象的一個實例
getName()返回此Class對象所表示的實體(類、接口、數組類、基本類型或void)名稱
Class [] getInterfaces()獲取當前Class對象的接口
Constructor[] getConstructors()返回一個包含某些Constructor對象的數組
Field[] getDeclaredFields()返回Field對象的一個數組
Method getMethod(String name,Class … paramTypes)返回一個Method對象,此對象的形參類型為paramType

2、Constructor 構造方法

        //使用反射機制時,只知道類的名稱(包名+類名)String classname = "com.ffyc.javareflect.User";//1.通過類名,獲得到類的Class對象Class aClass = Class.forName(classname);//2.通過類的Class對象,創建對象Object obj = aClass.newInstance();//獲得類中的構造方法,通過構造方法api中的方法創建對象Constructor constructor1 = aClass.getConstructor();  //獲得指定的公共構造方法Object obj1 = constructor1.newInstance();//無參構造方法Constructor constructor2 = aClass.getConstructor(String.class,String.class);Object obj2 = constructor2.newInstance("張三","1111");//有參構造方法System.out.println(obj1);System.out.println(obj2);Constructor[] constructors = aClass.getConstructors();//獲得所有公共的構造方法//雖然可以獲取私有構造方法,但是一般不建議操作私有成員,因為打破了封裝性aClass.getDeclaredConstructor();//獲得類中任意的構造方法,包含私有的

????????????????? ? ? ? ?

3、Method 方法

        //使用反射機制時,只知道類的名稱(包名+類名)String classname = "com.ffyc.javareflect.User";//1.通過類名,獲得到類的Class對象Class aClass = Class.forName(classname);//2.通過類的Class對象,創建對象Object obj = aClass.newInstance();//獲得類中指定名稱的成員方法Method method = aClass.getMethod("eat" );//調用訪問method.invoke(obj);

?????????????????????????????????? ???????? ? ? ???????????

4、Field 屬性

        //使用反射機制時,只知道類的名稱(包名+類名)String classname = "com.ffyc.javareflect.User";//1.通過類名,獲得到類的Class對象Class aClass = Class.forName(classname);//2.通過類的Class對象,創建對象Object obj = aClass.newInstance();//獲得類中成員變量//Field accountField = aClass.getField("account");//獲得指定名稱的公共的成員變量Field accountField = aClass.getDeclaredField("account");//獲得指定名稱的成員變量,包含私有的accountField.setAccessible(true);//設置允許直接訪問操作私有成員accountField.set(obj,"admin");System.out.println(obj);

???????????????? ? ? ? ? ?

模擬框架拿任意一個類的信息

        //使用反射機制時,只知道類的名稱(包名+類名)String classname = "com.ffyc.javareflect.User";//1.通過類名,獲得到類的Class對象Class aClass = Class.forName(classname);//2.通過類的Class對象,創建對象Object obj = aClass.newInstance();//演示通過屬性的get和set方法,對類中私有屬性進行賦值取值操作//模擬從數據庫中查詢到的數據HashMap<String,String> map = new HashMap<>();map.put("account", "admin");map.put("password", "1111");//先拿到類中所有的私有屬性Field[] declaredFields = aClass.getDeclaredFields();for (Field field : declaredFields){//根據屬性名,生成Set方法名稱String setmethod = "set"+field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);//通過Class對象,獲得對應的Set方法對象Method setmethodobj = aClass.getMethod(setmethod,field.getType());//調用Set方法setmethodobj.invoke(obj, map.get(field.getName()));}System.out.println(obj);

??????????????????????????????????????

模擬一個簡單的json轉換格式

public class JsonUtil {public static String objectToJson(Object object) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Class aclass = object.getClass();Field[] declaredFields = aclass.getDeclaredFields();String json = "{";for (Field field : declaredFields){//根據屬性名,生成Get方法名稱String getmethod = "get"+field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);//通過Class對象,獲得對應的Get方法對象Method getmethodobj = aclass.getMethod(getmethod);//調用Get方法json += field.getName() +":"+ (String) getmethodobj.invoke(object) + ",";}json = json.substring(0, json.length() - 1) + "}";return json;}public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {User user = new User();user.setAccount("admin");user.setPassword("1111");Car car = new Car();car.setName("寶馬");car.setColor("紅色");System.out.println(JsonUtil.objectToJson(user));System.out.println(JsonUtil.objectToJson(car));}
}

????????????????????????????????????????????????????????????? ? ??

反射的優缺點:

? ? 優點:

? ? ? ? ? ? 1、增加程序的靈活性,可以在運行的過程中動態對類進行修改和操作

? ? ? ? ? ? 2、提高代碼的復用率

? ? ? ? ? ? 3、可以在運行時輕松獲取任意一個類的方法、屬性,并且還能通過反射進行動態調用

? ? 缺點:

? ? ? ? ? ? 1、反射會涉及到動態類型的解析,導致性能要比非反射調用更低

? ? ? ? ? ? 2、使用反射技術通常要在一個沒有安全限制的程序運行.

? ? ? ? ? ? 3、反射可以繞過一些限制訪問的屬性或者方法,可能會導致破壞代碼本身的封裝性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80082.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80082.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80082.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ch10 課堂參考代碼

ch10 最小生成樹 生成樹&#xff1a;對于 n 個結點 m 條邊的無向圖 G&#xff0c;由全部 n 個結點和其中 n - 1 條邊構成的無向連通子圖稱為 G 的一棵生成樹。 如果圖 G 原本就不連通&#xff0c;則不存在生成樹&#xff0c;只存在生成森林。 最小生成樹&#xff08;Minimum…

費曼技巧及提高計劃

費曼技巧及提高計劃 一、什么是費曼技巧&#xff1f; 費曼技巧&#xff08;Feynman Technique&#xff09;由諾貝爾物理學獎得主理查德費曼提出&#xff0c;是一種通過“以教代學”來徹底理解復雜概念的學習方法。其核心邏輯是&#xff1a; “如果你不能簡單解釋一件事&#x…

LongRefiner:解決長文檔檢索增強生成的新思路

大語言模型與RAG的應用越來越廣泛&#xff0c;但在處理長文檔時仍面臨不少挑戰。今天我們來聊聊一個解決這類問題的新方法——LongRefiner。 背景問題&#xff1a;長文檔處理的兩大難題 使用檢索增強型生成&#xff08;RAG&#xff09;系統處理長文檔時&#xff0c;主要有兩個…

5月16日復盤-目標檢測開端

5月16日復盤 一、圖像處理之目標檢測 1. 目標檢測認知 ? Object Detection&#xff0c;是指在給定的圖像或視頻中檢測出目標物體在圖像中的位置和大小,并進行分類或識別等相關任務。 ? 目標檢測將目標的分割和識別合二為一。 ? What、Where 2. 使用場景 目標檢測用于…

MySQL基礎面試通關秘籍(附高頻考點解析)

文章目錄 一、事務篇&#xff08;必考重點&#xff09;1.1 事務四大特性&#xff08;ACID&#xff09;1.2 事務實戰技巧 二、索引優化大法2.1 索引類型全家福2.2 EXPLAIN命令實戰 三、存儲引擎選型指南3.1 InnoDB vs MyISAM 終極對決 四、SQL優化實戰手冊4.1 慢查詢七宗罪4.2 分…

Word圖片格式調整與轉換工具

軟件介紹 本文介紹的這款工具主要用于輔助Word文檔處理。 圖片排版功能 經常和Word打交道的人或許都有這樣的困擾&#xff1a;插入的圖片大小各異&#xff0c;排列也參差不齊。若不加以調整&#xff0c;遇到要求嚴格的領導&#xff0c;可能會讓人頗為頭疼。 而這款工具能夠統…

工業巡檢機器人 —— 機器人市場的新興增長引擎

摘要 在機器人產業蓬勃發展的當下&#xff0c;不同類型機器人的市場表現差異顯著。工業機械臂雖市場規模龐大&#xff0c;但已趨近飽和&#xff0c;陷入紅海競爭&#xff1b;人形機器人因技術瓶頸仍多停留于實驗室階段&#xff0c;距離大規模商用尚有較長距離。與之形成鮮明對比…

Oracle where條件執行先后順序

Oracle where條件執行先后順序 在Oracle數據庫中&#xff0c;WHERE子句的條件執行順序通常是根據你在WHERE子句中指定的條件來決定的&#xff0c;而不是按照某種固定的順序執行的。當你編寫一個WHERE子句時&#xff0c;你可以包含多個條件&#xff0c;這些條件可以是邏輯運算符…

在Linux中使用 times函數 和 close函數 兩種方式 打印進程時間。

times函數用于獲取當前進程時間,其函數原型如下所示: #include <sys/times.h> clock_t times(struct tms *buf); //使用該函數需要包含頭文件<sys/times.h>。 函數參數和返回值含義如下: buf:times()會將當前進程時間信息存在一個 struct tms 結構體數據…

Python文字轉語音TTS庫示例(edge-tts)

1. 安裝 pip install edge-tts2. 命令行使用 # 生成語音文件 # -f:要轉換語音的文本文件,例如一個txt文件 # --text:指明要保存的mp3的文本 # --write-media:指明保存的mp3文件路徑 # --write-subtitles:指定輸出字幕/歌詞路徑 # --rate:調整語速,+50%加快了50% # --v…

Elasticsearch性能調優全攻略:從日志分析到集群優化

#作者&#xff1a;獵人 文章目錄 前言搜索慢查詢日志索引慢寫入日志性能調優之基本優化建議性能調優之索引寫入性能優化提升es集群寫入性能方法&#xff1a;性能調優之集群讀性能優化性能調優之搜索性能優化性能調優之GC優化性能調優之路由優化性能調優之分片優化 前言 es里面…

MongoDB從入門到實戰之Windows快速安裝MongoDB

前言 本章節的主要內容是在 Windows 系統下快速安裝 MongoDB 并使用 Navicat 工具快速連接。 MongoDB從入門到實戰之MongoDB簡介 MongoDB從入門到實戰之MongoDB快速入門 MongoDB從入門到實戰之Docker快速安裝MongoDB 下載 MongoDB 安裝包 打開 MongoDB 官網下載頁面&…

Serverless,云計算3.0階段

Hi~各位讀者朋友們&#xff0c;感謝您閱讀本文&#xff0c;我是笠泱&#xff0c;本期簡單分享下Serverless。Serverless是一種云計算服務模式&#xff0c;為業務代碼提供運行環境及調度服務。開發者只需專注于編寫業務邏輯代碼&#xff0c;無需管理底層基礎設施&#xff08;如服…

eSearch:一款集截圖、OCR與錄屏于一體的多功能軟件

eSearch&#xff1a;一款集截圖、OCR與錄屏于一體的多功能軟件 軟件介紹 eSearch是一款專為Windows 10和11用戶設計的多功能軟件&#xff0c;集截圖、OCR文字識別、錄屏等功能于一體&#xff0c;且完全免費。其便捷版無需安裝&#xff0c;運行后最小化至托盤圖標&#xff0c;…

React學習———useContext和useReducer

useContext useContext是React的一個Hook&#xff0c;用于在函數組件中訪問上下文&#xff08;context&#xff09;的值。它可以幫助我們在組件樹中共享狀態&#xff0c;而不需要通過props一層層傳遞 特點 用于跨組件共享狀態需要配合React.createContext和Context.Provider…

安卓刷機模式詳解:Fastboot、Fastbootd、9008與MTK深刷

安卓刷機模式詳解&#xff1a;Fastboot、Fastbootd、9008與MTK深刷 一、刷機模式對比 1. Fastboot模式 簡介&#xff1a;傳統安卓底層刷機模式&#xff0c;通過USB連接電腦操作優點&#xff1a;支持大多數安卓設備&#xff0c;操作相對簡單缺點&#xff1a;需要設備進入特定…

HDFS的概述

HDFS組成構架&#xff1a; 注&#xff1a; NameNode&#xff08;nn&#xff09;&#xff1a;就是 Master&#xff0c;它是一個主管、管理者。 (1) 管理 HDFS 的名稱空間&#xff1b; (2) 配置副本策略。記錄某些文件應該保持幾個副本&#xff1b; (3) 管理數據塊&#xff0…

配置Spark環境

1.上傳spark安裝包到某一臺機器&#xff08;自己在finaShell上的機器&#xff09;。 2.解壓。 把第一步上傳的安裝包解壓到/opt/module下&#xff08;也可以自己決定解壓到哪里&#xff09;。對應的命令是&#xff1a;tar -zxvf 安裝包 -C /opt/module 3.重命名。進入/opt/mo…

Java筆記五

1 Math類 1.1 概述 tips&#xff1a;了解內容 查看API文檔&#xff0c;我們可以看到API文檔中關于Math類的定義如下&#xff1a; Math類所在包為java.lang包&#xff0c;因此在使用的時候不需要進行導包。并且Math類被final修飾了&#xff0c;因此該類是不能被繼承的。 Math…

QT 插槽實現

方法 1&#xff1a;使用 default property 實現標簽插入 通過定義 default property&#xff0c;可以使組件直接嵌套在目標組件中&#xff0c;類似于插槽機制。 CustomSlotExample.qml import QtQuick 2.15 import QtQuick.Controls 2.15// 定義一個支持插槽的自定義組件 Re…