深入淺出Java反射:掌握動態編程的藝術

  • 小程一言
  • 反射
    • 何為反射
    • 反射核心類
    • 反射的基本使用
      • 獲取`Class`對象
      • 創建對象
      • 調用方法
      • 訪問字段
    • 示例程序
    • 應用場景
    • 優缺點分析
      • 優點
      • 缺點
    • 注意
  • 再深入一些
    • 反射與泛型
    • 反射與注解
    • 反射與動態代理
    • 反射與類加載器
  • 結語

小程一言

本專欄是對Java知識點的總結。在學習Java的過程中,學習的筆記,加入自己的思考,結合各種資料的整理。

文章與程序一樣,一定都是不完美的,因為不完美,才擁有不斷追求完美的動力

以下是符合您要求的博客文章,主類名為crj,內容全面細致,深度適中,字數約5000字。

---

反射

Java反射是Java語言中一項強大的功能,它允許程序在運行時動態地獲取類的信息并操作類的屬性、方法和構造方法。反射機制為Java提供了極大的靈活性,廣泛應用于框架開發、動態代理、注解處理等場景。本文將詳細介紹Java反射的核心概念、使用方法以及注意事項,并通過示例代碼幫助讀者更好地理解。


何為反射

簡單來說,反射是指在程序運行時,能夠動態地獲取類的信息(如類名、方法、字段、構造方法等),并能夠操作這些信息。通過反射,我們可以在運行時創建對象、調用方法、訪問字段,甚至修改私有成員的值。

反射的核心類是java.lang.reflect包中的ClassMethodFieldConstructor。通過這些類,我們可以實現動態編程。

在這里插入圖片描述

反射核心類

  1. Class<T>: 表示一個類或接口的類型信息。通過Class對象可以獲取類的構造方法、方法和字段。
  2. Constructor<T>: 表示類的構造方法,用于創建對象。
  3. Method: 表示類的方法,用于調用方法。
  4. Field: 表示類的字段,用于訪問或修改字段的值。

反射的基本使用

獲取Class對象

要使用反射,首先需要獲取目標類的Class對象。以下是三種常見的獲取方式:

  • Class.forName("全限定類名"): 通過類的全限定名獲取Class對象。
  • 對象.getClass(): 通過對象實例獲取Class對象。
  • 類名.class: 直接通過類名獲取Class對象。
// 示例:獲取String類的Class對象
Class<?> clazz = Class.forName("java.lang.String");

創建對象

通過Class對象可以獲取類的構造方法,并調用newInstance()方法創建對象。

// 示例:通過反射創建String對象
Class<?> clazz = Class.forName("java.lang.String");
Constructor<?> constructor = clazz.getConstructor(); // 獲取無參構造方法
Object obj = constructor.newInstance(); // 創建對象
System.out.println("創建的對象: " + obj);

調用方法

通過Class對象可以獲取類的方法,并調用invoke()方法執行方法。

// 示例:通過反射調用String的length()方法
Class<?> clazz = Class.forName("java.lang.String");
Method method = clazz.getMethod("length"); // 獲取length()方法
int length = (int) method.invoke("Hello"); // 調用方法
System.out.println("字符串長度: " + length);

訪問字段

通過Class對象可以獲取類的字段,并訪問或修改字段的值。

// 示例:通過反射訪問Integer的value字段
Class<?> clazz = Class.forName("java.lang.Integer");
Field field = clazz.getDeclaredField("value"); // 獲取value字段
field.setAccessible(true); // 設置可訪問私有字段
int value = (int) field.get(10); // 獲取字段值
System.out.println("字段值: " + value);

在這里插入圖片描述

示例程序

以下是一個完整的示例程序,展示了如何使用反射創建對象、調用方法和訪問字段。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class crj {public static void main(String[] args) {try {// 1. 獲取Class對象Class<?> clazz = Class.forName("java.lang.String");// 2. 創建對象Constructor<?> constructor = clazz.getConstructor();Object obj = constructor.newInstance();System.out.println("創建的對象: " + obj);// 3. 調用方法Method method = clazz.getMethod("length");int length = (int) method.invoke("Hello");System.out.println("字符串長度: " + length);// 4. 訪問字段Class<?> integerClass = Class.forName("java.lang.Integer");Field field = integerClass.getDeclaredField("value");field.setAccessible(true);int value = (int) field.get(10);System.out.println("Integer的value字段值: " + value);} catch (Exception e) {e.printStackTrace();}}
}

應用場景

  1. 動態代理: 在運行時創建代理對象,例如Spring AOP。
  2. 框架開發: 如Spring通過反射管理Bean的生命周期。
  3. 注解處理: 在運行時讀取注解信息,例如JUnit的測試框架。
  4. 工具開發: 如IDE的代碼提示功能。

優缺點分析

優點

  • 靈活性高: 可以在運行時動態操作類和方法。
  • 功能強大: 適用于框架和工具開發。

缺點

  • 性能較低: 反射操作比直接調用慢。
  • 破壞封裝性: 可以訪問私有成員,可能導致安全問題。
  • 代碼可讀性差: 反射代碼通常難以理解和維護。

注意

  1. 性能問題: 反射操作較慢,頻繁使用時需謹慎。
  2. 安全性: 反射可以繞過訪問控制,需確保代碼的安全性。
  3. 異常處理: 反射操作可能拋出IllegalAccessExceptionInvocationTargetException等異常,需妥善處理。

在這里插入圖片描述

再深入一些

將能聯系到的地方都牽連一下,希望能給你更多的思考

反射與泛型

Java反射機制在處理泛型時需要注意類型擦除的問題。由于Java的泛型是通過類型擦除實現的,因此在運行時無法直接獲取泛型的具體類型信息。但是,可以通過ParameterizedType等接口來獲取泛型的信息。

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class crj{public static class GenericClass<T> {public void printType() {Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];System.out.println("泛型類型: " + type);}}public static void main(String[] args) {GenericClass<String> genericClass = new GenericClass<String>() {};genericClass.printType();}
}

反射與注解

Java反射機制可以用于讀取和處理注解。通過反射,我們可以在運行時獲取類、方法、字段上的注解信息,并根據注解的值執行相應的邏輯。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {String value();
}public class AnnotationReflectionExample {@MyAnnotation("Hello, Annotation!")public void annotatedMethod() {System.out.println("這是一個帶有注解的方法");}public static void main(String[] args) throws Exception {Method method = AnnotationReflectionExample.class.getMethod("annotatedMethod");MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);System.out.println("注解值: " + annotation.value());}
}

在這里插入圖片描述

反射與動態代理

Java反射機制在動態代理中扮演著重要角色。通過Proxy類和InvocationHandler接口,我們可以在運行時創建代理對象,并在調用方法時執行額外的邏輯。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface MyInterface {void doSomething();
}public class DynamicProxyExample {public static void main(String[] args) {MyInterface realObject = new MyInterface() {@Overridepublic void doSomething() {System.out.println("真實對象的方法");}};MyInterface proxyObject = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class<?>[] { MyInterface.class },new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法調用前");Object result = method.invoke(realObject, args);System.out.println("方法調用后");return result;}});proxyObject.doSomething();}
}

反射與類加載器

Java反射機制與類加載器密切相關。通過自定義類加載器,我們可以在運行時動態加載類,并使用反射機制操作這些類。

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;public class CustomClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] classData = loadClassData(name);return defineClass(name, classData, 0, classData.length);}private byte[] loadClassData(String className) {InputStream inputStream = getClass().getClassLoader().getResourceAsStream(className.replace('.', '/') + ".class");ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();int bufferSize = 4096;byte[] buffer = new byte[bufferSize];int bytesRead;try {while ((bytesRead = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, bytesRead);}} catch (Exception e) {e.printStackTrace();}return byteArrayOutputStream.toByteArray();}public static void main(String[] args) throws Exception {CustomClassLoader customClassLoader = new CustomClassLoader();Class<?> clazz = customClassLoader.loadClass("com.example.MyClass");Object obj = clazz.getDeclaredConstructor().newInstance();Method method = clazz.getMethod("myMethod");method.invoke(obj);}
}

在這里插入圖片描述

結語

Java反射是一項強大的功能,它為Java提供了動態編程的能力。通過反射,我們可以在運行時獲取類的信息并操作類的成員。盡管反射具有很高的靈活性,但也存在性能和安全性的問題。在實際開發中,應根據需求合理使用反射,避免濫用。

希望本文能幫助你更好地理解Java反射機制!如果你有任何問題或建議,歡迎在評論區留言。

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

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

相關文章

【算法與數據結構】并查集詳解+題目

目錄 一&#xff0c;什么是并查集 二&#xff0c;并查集的結構 三&#xff0c;并查集的代碼實現 1&#xff0c;并查集的大致結構和初始化 2&#xff0c;find操作 3&#xff0c;Union操作 4&#xff0c;優化 小結&#xff1a; 四&#xff0c;并查集的應用場景 省份…

C語言簡單練習題

文章目錄 練習題一、計算n的階乘bool類型 二、計算1!2!3!...10!三、計算數組arr中的元素個數二分法查找 四、動態打印字符Sleep()ms延時函數system("cls")清屏函數 五、模擬用戶登錄strcmp()函數 六、猜數字小游戲產生一個隨機數randsrandRAND_MAX時間戳time() 示例 …

ShenNiusModularity項目源碼學習(8:數據庫操作)

ShenNiusModularity項目使用SqlSugar操作數據庫。在ShenNius.Repository項目中定義了ServiceCollectionExtensions.AddSqlsugarSetup函數注冊SqlSugar服務&#xff0c;并在ShenNius.Admin.API項目的ShenniusAdminApiModule.OnConfigureServices函數中調用&#xff0c;SqlSugar所…

MATLAB圖像處理:圖像特征概念及提取方法HOG、SIFT

圖像特征是計算機視覺中用于描述圖像內容的關鍵信息&#xff0c;其提取質量直接影響后續的目標檢測、分類和匹配等任務性能。本文將系統解析 全局與局部特征的核心概念&#xff0c;深入講解 HOG&#xff08;方向梯度直方圖&#xff09;與SIFT&#xff08;尺度不變特征變換&…

java枚舉類型的查找

AllArgsConstructor Getter public enum FileFilterRangeEnum {FILE_NAME("文件名稱","fileName"),FILE_CONTENT("文件內容","fileContent");private final String text;private final String value;// 根據傳入的字符串值查找對應的枚…

小白win10安裝并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路徑最好都是全英文 win10安裝并配置yt-dlp 一、下載1.下載yt-dlp2. fffmpeg下載 二、配置環境三、cmd操作四、yt-dlp下視頻操作 一、下載 1.下載yt-dlp yt-dlp地址 找到win的壓縮包點下載&#xff0c;并解壓 2. fffmpeg下載 ffmpeg官方下載 …

【技術解析】MultiPatchFormer:多尺度時間序列預測的全新突破

今天給我大家帶來一篇最新的時間序列預測論文——MultiPatchFormer。這篇論文提出了一種基于Transformer的創新模型&#xff0c;旨在解決時間序列預測中的關鍵挑戰&#xff0c;特別是在處理多尺度時間依賴性和復雜通道間相關性時的難題。MultiPatchFormer通過引入一維卷積技術&…

145,【5】 buuctf web [GWCTF 2019]mypassword

進入靶場 修改了url后才到了注冊頁面 注測后再登錄 查看源碼 都點進去看看 有個反饋頁面 再查看源碼 又有收獲 // 檢查$feedback是否為數組 if (is_array($feedback)) {// 如果是數組&#xff0c;彈出提示框提示反饋不合法echo "<script>alert(反饋不合法);<…

CTF-WEB: 利用iframe標簽利用xss,waf過濾后再轉換漏洞-- N1ctf Junior display

核心邏輯 // 獲取 URL 查詢參數的值 function getQueryParam(param) { // 使用 URLSearchParams 從 URL 查詢字符串中提取參數 const urlParams new URLSearchParams(window.location.search); // 返回查詢參數的值 return urlParams.get(param); } // 使用 DOMPuri…

晶閘管主要參數分析與損耗計算

1. 主要參數 斷態正向可重復峰值電壓 :是晶閘管在不損壞的情況下能夠承受的正向最大阻斷電壓。斷態正向不可重復峰值電壓 :是晶閘管只有一次可以超過的正向最大阻斷電壓,一旦晶閘管超過此值就會損壞,一般情況下 反向可重復峰值電壓 :是指晶閘管在不損壞的情況下能夠承受的…

el-select 設置寬度 沒效果

想實現下面的效果&#xff0c;一行兩個&#xff0c;充滿el-col12 然后設置了 width100%,當時一直沒有效果 解決原因&#xff1a; el-form 添加了 inline 所以刪除inline屬性 即可

Python創建FastApi項目模板

1. 項目結構規范 myproject/ ├── app/ │ ├── core/ # 核心配置 │ │ ├── config.py # 環境配置 │ │ └── security.py # 安全配置 │ ├── routers/ # 路由模塊 │ │ └── users.py # 用戶路由 │ ├…

面試完整回答:SQL 分頁查詢中 limit 500000,10和 limit 10 速度一樣快嗎?

首先&#xff1a;在 SQL 分頁查詢中&#xff0c;LIMIT 500000, 10 和 LIMIT 10 的速度不會一樣快&#xff0c;以下是原因和優化建議&#xff1a; 性能差異的原因 LIMIT 10&#xff1a; 只需要掃描前 10 條記錄&#xff0c;然后返回結果。 性能非常高&#xff0c;因為數據庫只…

一款利器提升 StarRocks 表結構設計效率

CloudDM 個人版是一款數據庫數據管理客戶端工具&#xff0c;支持 StarRocks 可視化建表&#xff0c;創建表時可選擇分桶、配置數據模型。目前版本持續更新&#xff0c;在修改 StarRocks 表結構方面進一步優化&#xff0c;大幅提升 StarRocks 表結構設計效率。當前 CloudDM 個人…

數量5 - 平面圖形、立體幾何

目錄 一、平面幾何問題1.三角形2.其他圖形二、立體幾何與特殊幾何1.表面積2.體積3.等比放縮(簡單)4.幾何最值(簡單)5.最短路徑一、平面幾何問題 平面圖形: 立體圖形: 1.三角形 特殊直角

CAS單點登錄(第7版)7.授權

如有疑問&#xff0c;請看視頻&#xff1a;CAS單點登錄&#xff08;第7版&#xff09; 授權 概述 授權和訪問管理 可以使用以下策略實施授權策略以保護 CAS 中的應用程序和依賴方。 服務訪問策略 服務訪問策略允許您定義授權和訪問策略&#xff0c;以控制對向 CAS 注冊的…

53倍性能提升!TiDB 全局索引如何優化分區表查詢?

作者&#xff1a; Defined2014 原文來源&#xff1a; https://tidb.net/blog/7077577f 什么是 TiDB 全局索引 在 TiDB 中&#xff0c;全局索引是一種定義在分區表上的索引類型&#xff0c;它允許索引分區與表分區之間建立一對多的映射關系&#xff0c;即一個索引分區可以對…

排序(Sortable)

排序&#xff08;Sortable&#xff09; 引言 在計算機科學和數據管理領域&#xff0c;排序算法是一項基本且重要的技能。排序算法能夠將一組無序的數據轉換為有序的數據&#xff0c;從而便于后續的數據處理和分析。本文將深入探討排序算法的基本概念、常用排序方法、以及它們…

紫光展銳蜂窩物聯網芯片V8850榮獲國密一級安全認證

近日&#xff0c;紫光展銳蜂窩物聯網芯片V8850榮獲國密一級認證&#xff0c;標志著展銳V8850在安全能力方面獲得權威認可&#xff0c;位居行業領先水平。這是紫光展銳繼短距物聯網芯片V5663在2020獲得ARM PSA Level 2認證&#xff0c;蜂窩物聯網芯片V8811在2021年獲得ARM PSA L…

I.MX6ull-I2C

一,I2C總線介紹 I2C(Inter-Integrated Circuit 集成電路)總線是Philips公司在八十年代初推出的一種串行、半雙工的總 線&#xff0c;主要用于近距離、低速的芯片之間的通信&#xff1b;I2C總線有兩根雙向的信號線&#xff0c;一根數據線SDA用于收 發數據&#xff0c;一根時鐘線…