java反射(詳細教程)

我們平常創建類的實例并調用類中成員需要建立在一個前提下,就是已經知道類名和類中成員的信息,靈活性大大降低。甚至在一些項目中還需要修改源碼來滿足使用條件,大大降低了操作的靈活性。

Java 反射(Reflection)是 Java 語言的一個重要特性,它允許程序在運行時而不是編譯時獲取類中成員,并且可以動態地操作這些類的成員。

在講反射之前,我們先聊一聊反射機制中必不可少的一環:配置文件。我需要提前將我的類名,成員名填寫到配置文件中去。這樣在調用時就可以直接讀取配置文件中的信息。相較于讀取普通文件,配置文件的讀取和調用更加簡單。

一、讀取配置文件:

1.創建配置文件:在指定的路徑下(通常我放在src目錄下,不為別的,就因為路徑名簡單)創建一個以“.properties”為結尾的File文件(普通的鍵值對形式)作為配置文件。

2.填寫配置文件內容:以“鍵=值”的形式填寫,不必添加空格和引號,調用時通過鍵的字符串形式調用(后面會舉例說明)。

3.創建配置文件對象:首先new一個配置文件的對象,使用load方法將配置文件中的內容讀取到配置文件對象中。

load方法提供了兩種重載,既可以通過字節流輸入,也可以通過字符流輸入。推薦使用字節流輸入,配置文件通常為全英文形式,字節流輸入效率高。

4.獲取配置文件中的內容:Properties類提供了一種getProperty(鍵)方法來獲取配置文件中的信息,需要在方法中寫入一個鍵,就會返回一個String類型鍵對應的值。這個String類型的值就是我們要從配置文件中拿到的值。

Exam我提前在src目錄下創建了一個名為“p.properties”的配置文件并提前寫好鍵值對來表示需要需要反射文件的路徑、屬性和方法。路徑表示com.reflectNewEdu包下的名為“reflectEdu”的文件,我需要反射這個文件中的成員。

//配置文件的內容
//路徑
className = com.reflectNewEdu.reflectEdu
//屬性
ObjName = str
//方法
methodName = printContent
methodName1 = printSome

Exam在reflectEdu文件中需要寫一些成員來幫助我們進行實驗。

public class reflectEdu {//分別一個public和一個private屬性public int num = 123;private String str = "字符串";//方法public void printContent() {System.out.println("輸出內容");}private void printSome() {System.out.println("輸出一些東西");}
}

Exam創建一個Test類,在Test類中填寫main方法具體實現反射:

二、獲取類對象(main函數中):

1.首先按照上面的步驟創建配置文件對象,并使用字節流加載配置文件進配置文件對象中。

Properties properties = new Properties();
properties.load(new FileReader("src/p.properties"));

2.為了繞過對象階段創建類對象,Class.forName(類全名)提供了一種在硬盤階段獲取類中成員的方法。Class.forName(類全名) ?的核心作用,是通過類的全限定名,讓JVM加載這個類,并返回一個代表該類“模板”的 Class ?對象。此時僅完成了“類的加載”,并沒有創建任何屬于這個類的具體對象,就像拿到了一張“汽車設計圖紙”,但還沒造出真正能開的汽車。

該方法需要寫入一個String類型的類全名,我們通過getProperty(鍵)方法從配置文件中拿到這個類全名。

Class.forName()方法返回一個Class類型的對象,這是一個類對象。類對象并不是哪個類的實例,但可以通過這個類對象下的方法獲取到類中的成員,甚至是獲取類的實例。(還是挺抽象的

Class class0 = Class.forName(properties.getProperty("className"));

三、獲取類對象中的成員:

一、屬性(返回Field類型,需要import java.lang.reflect.Field;):

? ? ? ? 1.獲取當前類里所有屬性:getDeclaredFields(); (返回數組)

? ? ? ? 2.通過屬性名獲取屬性:getDeclaredField(屬性名);

? ? ? ? 3.獲取所有公共類型屬性:getFields();(返回數組)

? ? ? ? 4.獲取公共類型中指定的屬性:getField(屬性名);

? ? ? ? 5.設置對象的屬性:屬性對象.set(對象名,屬性值)

? ? ? ? 當屬性被private修飾無法被調用時,可以使用:類對象名.setAccessible(true); 來進行暴力反射。

二、方法(返回Method類型,需要import java.lang.reflect.Method;):

? ? ? ? 1.獲取類里所有方法:getDeclaredMethods();(返回數組)

? ? ? ? 2.通過方法名獲取方法:getDeclaredMethod(方法名);

? ? ? ? 3.獲取所有公共類型方法:getMethods();(返回數組)

? ? ? ? 4.獲取公共類型中指定的方法:getMethod(方法名);

? ? ? ? 5.運行指定的方法:方法對象.invoke(對象名, 參數);?

? ? ? ? 第一個為對象名,第二個為參數名,如果沒有參數可以不用輸入,允許暴力反射。

三、構造方法(返回Constructor類型,需要import java.lang.reflect.Constructor;):

? ? ? ? 1.獲取類里所有構造方法:getDeclaredConstructors();(返回數組)

? ? ? ? 2.獲取指定的無參構造方法:getDeclaredConstructor();

? ? ? ? 3.獲取指定的帶有參數的構造方法(舉例:帶有String和int類型的兩個參數的構造方法):getDeclaredConstructor(String.class,int.class);

? ? ? ? 4.獲取所有公共類型的構造方法:getConstructors();(返回數組)

? ? ? ? 5.獲取公共類型中指定的一個方法(有參或無參):getConstructor();

? ? ? ? 6.執行無參構造方法:Object 新變量名 = 構造方法對象/類對象名.newInstance(); 相當于Object obj = new ();?

? ? ? ? 7.執行有參的構造方法:Object 新變量名 = 構造方法對象.newInstance(參數);

需要注意我標藍的地方,都需要傳入一個類對象,那么如何獲取類的實例對象呢?

四、獲取類的實例對象:

1.通過構造方法獲取:我們已經拿到指向我們需要反射的類的對象了,直接通過getDeclaredConstructor()方法獲取一個構造方法(我這里是無參的),再執行構造方法中的newInstance()方法不就行了嘛。

代碼:

Constructor con = class0.getConstructor();
Object object = con.newInstance();

注:我們提前無法預測給類起的名字是什么,所以需要用它們共同的父類Object對象來接受。

2.通過類對象獲取:對類對象直接使用newInstance()方法,這樣無需知道類名,就可以創建類的實例對象啦。

Object object = class0.newInstance();

有了類的實例對象,我們就可以使用上面標藍的方法了,比如調用類中的方法等。

由此,反射的整個過程就實現完了如果有什么地方不明白的話,可以私信討論( o >o)/。

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

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

相關文章

消息隊列-初識kafka

優缺點 消息隊列的優點: 實現系統解耦: :::color5 系統解耦解釋 有 MQ 時是 “服務 A 發消息到隊列,其他服務從隊列拿消息,新增服務接隊列就行”;無 MQ 時是 “服務 A 直接調其他服務的接口 / 依賴,新增 / …

實踐《數字圖像處理》之Canny邊緣檢測、霍夫變換與主動二值化處理在短線段清除應用中的實踐

在最近的圖像處理項目中,其中一個環節:圖片中大量短線(不是噪聲),需要在下一步處理前進行清除。在確定具體實現時,碰到了Canny邊緣檢測、霍夫變換與主動二值化處理的辯證使用,相關邏輯從圖片灰度…

vue3與ue5通信-工具類

工具 ue5-simple.js /*** UE5 通信工具* 兩個核心方法:發送消息和接收消息*/// 確保全局對象存在 if (typeof window ! undefined) {window.ue window.ue || {};window.ue.interface window.ue.interface || {}; }/*** 生成 UUID*/ function generateUUID() {retu…

在kotlin中如何使用像java中的static

在 Kotlin 中,沒有直接的 static 關鍵字,但有幾種等效的方式來實現 Java 中靜態成員的功能: 1. 伴生對象 (Companion Object) - 最常用 class MyClass {companion object {// 靜態常量const val STATIC_CONSTANT "constant value"…

如何在 Spring Boot 中指定不同的配置文件?

介紹 Spring Boot 提供了多種方式來管理和加載配置文件,特別是在多環境配置下,比如開發、測試和生產環境。通過指定不同的配置文件,可以靈活地調整應用程序的行為,以適應不同的需求。本文將介紹在 Spring Boot 中如何指定使用不同…

在centOS源碼編譯方式安裝MySQL5.7

一、前言 在生產環境中部署數據庫時,很多人會選擇直接使用 yum/apt 包管理器 安裝 MySQL,這樣簡單快速,但缺點是版本受限,靈活性不足。對于需要指定版本、啟用特定編譯參數或優化的場景,源碼編譯安裝 MySQL 就顯得非常…

探討Hyperband 等主要機器學習調優方法的機制和權衡

本篇文章Master Hyperband — An Efficient Hyperparameter Tuning Method in Machine Learning深入探討了Hyperband這一高效的超參數調優方法。文章的技術亮點在于其結合了多臂老虎機策略和逐次減半算法,能夠在大搜索空間中快速剔除表現不佳的配置,從而…

Mysql:InnoDB 關鍵特性

目錄 一、插入緩沖(Change Buffer)→ 快遞驛站的 “臨時存放區” 二、兩次寫(Double Write)→ 重要文件的 “備份存檔” 三、自適應哈希索引(AHI)→ 圖書館的 “熱門書快捷查找區” 四、異步 IO&#x…

STM32-----SPI

SPI簡介SCK:和I2C中SCL的時鐘線一個作用,都是在高電平拿出數據,在低電平寫數據MOSI:主機輸出從機輸入MISO:主機輸入從機輸出,只有當對應從機的SS為低電平,從機的MISO引腳才能設置推挽輸出,當從機SS為高電平時&#xff…

華為考試:HCIE數通考試難度分析

隨著信息技術的飛速發展,網絡技術已成為支撐各行各業運轉的重要基礎,市場對高水平網絡技術人才的需求持續增長。HCIE作為華為認證體系中的最高級別認證,代表了網絡技術領域的專業頂尖水平。本文將對HCIE數通認證的考試內容、難度及備考策略進…

一些常用的激活函數及繪圖

深度網絡的一些常用激活函數,并通過matplot繪制出來: import matplotlib.pyplot as plt import numpy as npdef relu(x):return np.maximum(0, x)def leaky_relu(x, alpha0.01):return np.where(x > 0, x, alpha * x)def gelu(x):return 0.5 * x * (1…

AE蘋果手機iPhone 17展示動畫片頭模板 App Promo Phone 17 Pro

專為 App 發布會、電商促銷、新品宣傳 打造的 iPhone 17 Pro 動畫展示 AE 模板。 4K 超清分辨率 26 張可替換照片位,無需第三方插件,拖拽即可輸出專業級手機宣傳片。 核心亮點 4K 超清:38402160 分辨率,大屏投放與社媒高清壓縮無…

基于Python的云原生TodoList Demo 項目,驗證云原生核心特性

以下是一個基于 Python 的云原生 TodoList Demo 項目,涵蓋 容器化、Kubernetes 編排、CI/CD、可觀測性、彈性擴縮容 等核心云原生特性,代碼簡潔且附詳細操作指南,適合入門學習。項目概覽 目標:實現一個支持增刪改查(CR…

go 日志的分裝和使用 Zap + lumberjack

自帶的log無法滿足 按大小輪轉 ,按天數清理舊日志 ,自動壓縮 ,限制備份數量 ,防止磁盤寫滿 ,生產環境推薦 等 使用 Zap lumberjack package mainimport ("go.uber.org/zap""go.uber.org/zap/zapcore&q…

【.Net技術棧梳理】01-核心框架與運行時(CLR)

文章目錄1 .NET Runtime(CLR-公共語言運行時)1.1 中間語言 IL1.1.1 從源代碼到通用中間語言(IL)1.1.2 運行時加載:CLR登場1.1.3 核心步驟:即時編譯 (JIT Compilation)1.1.4 執行與內存管理(GC&a…

Claude Code 平替:OpenAI發布 Codex CLI ,GPT-5 國內直接使用

openai推出的命令行編程工具codex已經可以使用最新 GPT-5 模型,擁有可媲美 Claude Code 的 AI 編碼能力。本文將指導你在 Windows 系統上部署原生的 Codex CLI 程序,并接入超低價中轉 API,讓你在國內直接用上超高性價比的 OpenAI Codex CLI 應…

在VS2022的WPF仿真,為什么在XAML實時預覽點擊 ce.xaml頁面控件,卻不會自動跳轉到具體代碼,這樣不方便我修改代碼,

在VS2022的WPF仿真,為什么在XAML實時預覽點擊 WpfApp1\FunctionalModule\08Replace\Replace.xaml頁面控件,卻不會自動跳轉到具體代碼,這樣不方便我修改代碼,

Git Bash 別名

有些常用的指令參數非常多,每次都要輸入好多參數,我們可以使用別名。Linux 系統中很多 shell,包括 bash,sh,zsh,dash 和 korn 等,不管哪種 shell 都會有一個 .bashrc 的隱藏文件,它就…

Centos7部署ceph存儲

一、準備5臺centos7主機 node節點雙網卡&#xff08;1個內部檢測&#xff0c;1個外部使用&#xff09;node節點都添加新網卡關閉防火墻和上下文都需要添加hosts文件都需要cat > /etc/hosts << EOF > 127.0.0.1 localhost localhost.localdomain localhost4 loca…

2025.9.10總結

今日感悟&#xff1a;刷到00后下班去菜市場撿菜的熱點視頻&#xff0c;確實挺有意思&#xff0c;不得不說&#xff0c;又省錢又好玩。雖然每天晚上能免費領個25塊錢的水果回去&#xff0c;但確實沒有什么新鮮感了。別人下班還能撿撿菜放松下&#xff0c;我下班&#xff0c;除了…