Java基礎關鍵_031_反射(一)

目? 錄

一、概述

二、獲取 Class?的四種方式

1.Class.forName("完整全限定類名")

2.getClass()

3.class 屬性

4.通過類加載器獲取

三、通過反射機制實例化對象

?1.newInstance()(已過時)

?2.配置文件利用反射機制實例化對象

?四、反射 Class 的 Field

1.獲取 Person 的屬性

2.反編譯 String 類的屬性

3.通過反射為對象屬性賦值


一、概述

  1. 反射機制是 JDK 中的一套類庫,可以幫助操作或讀取字節碼文件;
  2. 很多 Java 框架底層都是基于反射機制實現的;
  3. 部分核心類:
    1. java.lang.Class:實例代表某個 class 文件 或 某一類型;
    2. java.lang.reflect.Field:實例代表類中的屬性或字段;
    3. java.lang.reflect.Constructor:實例代表類中的構造方法;
    4. java.lang.reflect.Method:實例代表類中的方法。

二、獲取 Class?的四種方式

1.Class.forName("完整全限定類名")

  1. 全限定類名含有包名,是 lang 包下的,【 java.lang 】也不可省略;
  2. 參數是字符串類型;
  3. 若類不存在,則會報 【 java.lang.ClassNotFoundException】異常;
  4. 此方法的執行,會導致類加載。
public class ReflectTest {static {System.out.println("static block");}public static void main(String[] args) throws ClassNotFoundException {Class<?> aClass1 = Class.forName("reflecttest.ReflectTest");System.out.println(aClass1);Class<?> aClass2 = Class.forName("java.lang.Integer");System.out.println(aClass2);}
}


2.getClass()

  1. ?該方法通過引用去調用;
  2. 某類型的字節碼文件在內存中僅存儲一份。
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException {Class<?> aClass1 = Class.forName("java.lang.String");System.out.println(aClass1);String str = "hello";Class<?> aClass2 = str.getClass();System.out.println(aClass2);System.out.println(aClass1 == aClass2);Class<?> aClass3 = Class.forName("reflecttest.ReflectTest");System.out.println(aClass3);ReflectTest reflectTest = new ReflectTest();Class<? extends ReflectTest> aClass4 = reflectTest.getClass();System.out.println(aClass4);System.out.println(aClass3 == aClass4);}
}


3.class 屬性

? ? ? ? 在 Java 中,任何類型(包括基本數據類型)都有 class 屬性,可以通過這個屬性獲取 Class 實例。

public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException {Class<Integer> intClass = int.class;Class<Integer> integerClass = Integer.class;System.out.println(intClass);   // intSystem.out.println(integerClass);   // java.lang.Integer}
}

4.通過類加載器獲取

public class ReflectLoader {public static void main(String[] args) throws ClassNotFoundException {ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader);Class<?> aClass = systemClassLoader.loadClass("java.lang.String");System.out.println(aClass);}
}

? ? ? ? ?有關類加載器的部分細節,將在下一節進行討論。


三、通過反射機制實例化對象

? ? ? ? 那么,獲取到 Class 有什么用處呢?

? ? ? ? 這就是通過反射機制實例化對象。

?1.newInstance()(已過時)

public class Person {private String name;private int age;public Person() {System.out.println("Person 無參構造方法");}public Person(String name, int age) {System.out.println("Person 有參構造方法");this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> personClass = Class.forName("reflecttest.Person");System.out.println(personClass);Person person = (Person) personClass.newInstance();System.out.println(person);}
}
  1. 以上代碼通過 personClass 實例化 Person 類型對象;
  2. 原理:調用 Person 的無參構造方法實例化對象;
  3. 使用此方法實現對象實例化,必須保證該類存在無參構造方法,否則會報【java.lang.InstantiationException】異常;
  4. 從 jdk 9 開始,該方法被標注已過時。


?2.配置文件利用反射機制實例化對象

# classInfo.properties 文件
className=reflecttest.Person
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {ResourceBundle resourceBundle = ResourceBundle.getBundle("reflecttest\\classInfo"); // 加載classInfo.properties文件String className = resourceBundle.getString("className");   // 獲取className的值Class<?> aClass = Class.forName(className);Object o = aClass.newInstance();System.out.println(o);}
}

? ? ? ? 那么,在想要靈活實例化其他對象時,無需修改 java 文件,只需要修改配置文件即可。例如:將實例化 Person 對象改為 實例化 Date 對象。

# classInfo.properties 文件
className=java.util.Date


?四、反射 Class 的 Field

1.獲取 Person 的屬性

public class Person {public String name;private int age;protected String sex;public static String country;public static final String job = "程序員";
}
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {// 反射獲取類信息Class<?> aClass = Class.forName("reflecttest.Person");// 獲取類中的所有被 public 修飾的屬性Field[] fields = aClass.getFields();for (Field field : fields) {System.out.print(field.getName() + "    "); // name    country    job}System.out.println();// 獲取類中的所有屬性Field[] declaredFields = aClass.getDeclaredFields();for (Field declaredField : declaredFields) {// 獲取屬性名System.out.print(declaredField.getName() + "    "); // name    age    sex    country    job}System.out.println();for (Field declaredField : declaredFields) {// 獲取屬性類型System.out.print(declaredField.getType().getName() + "    "); // java.lang.String    int    java.lang.String    java.lang.String    java.lang.String}System.out.println();for (Field declaredField : declaredFields) {// 獲取屬性類型簡單名稱System.out.print(declaredField.getType().getSimpleName() + "    "); // String    int    String    String    String}System.out.println();for (Field declaredField : declaredFields) {// 獲取屬性的修飾符System.out.print(declaredField.getModifiers() + "    ");    // 1    2    4    9    25}System.out.println();for (Field declaredField : declaredFields) {// 獲取屬性的修飾符名稱System.out.print(Modifier.toString(declaredField.getModifiers()) + "    ");    // public    private    protected    public static    public static final}}
}


2.反編譯 String 類的屬性

public class ReflectTest {public static void main(String[] args) {String str = new String();// 獲取類信息Class<? extends String> aClass = str.getClass();// 獲取類修飾符String classMod = Modifier.toString(aClass.getModifiers());// 獲取簡單類名String className = aClass.getSimpleName();// 獲取簡單父類名String classSupName = aClass.getSuperclass().getSimpleName();// 獲取父類接口Class<?>[] classInterfaces = aClass.getInterfaces();// 獲取所有屬性Field[] declaredFields = aClass.getDeclaredFields();// 字符串拼接StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(classMod);stringBuilder.append(" class ");stringBuilder.append(className);stringBuilder.append(" extends ");stringBuilder.append(classSupName);if (classInterfaces.length > 0) {stringBuilder.append(" implements ");for (int i = 0; i < classInterfaces.length; i++) {stringBuilder.append(classInterfaces[i].getSimpleName());if (i != classInterfaces.length - 1) {stringBuilder.append(", ");}}}stringBuilder.append(" {\n");for (Field declaredField : declaredFields) {stringBuilder.append("\t");// 獲取屬性修飾符stringBuilder.append(Modifier.toString(declaredField.getModifiers()));stringBuilder.append(" ");// 獲取屬性類型stringBuilder.append(declaredField.getType().getSimpleName());stringBuilder.append(" ");// 獲取屬性名stringBuilder.append(declaredField.getName());stringBuilder.append(";\n");}stringBuilder.append("}");System.out.println(stringBuilder);}
}


3.通過反射為對象屬性賦值

  1. 三要素:對象、屬性、值。缺一不可;
  2. 若屬性不是 public 的,運行會報【java.lang.IllegalAccessException】異常,需要通過 setAccessible(true) 打破封裝;
public class Person {public String name;private int age;protected String sex;public static String country;public static final String job = "程序員";
}
public class FieldTest {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {Person person = new Person();// 獲取Person類Class<? extends Person> aClass = person.getClass();// 獲取屬性Field name = aClass.getDeclaredField("name");Field age = aClass.getDeclaredField("age");Field sex = aClass.getDeclaredField("sex");Field country = aClass.getDeclaredField("country");Field job = aClass.getDeclaredField("job");// 設置屬性可訪問age.setAccessible(true);sex.setAccessible(true);// 設置屬性值name.set(person, "小明");age.set(person, 23);sex.set(person, "男");country.set(person, "中國");// 獲取屬性值System.out.println("姓名:" + name.get(person));System.out.println("年齡:" + age.get(person));System.out.println("性別:" + sex.get(person));System.out.println("國籍:" + country.get(person));System.out.println("職業:" + job.get(person));}
}

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

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

相關文章

MySQL高級語句深度解析與應用實踐

一、窗口函數&#xff1a;數據分析的利器 1. 窗口函數基礎概念 窗口函數(Window Function)是MySQL 8.0引入的強大特性&#xff0c;它可以在不減少行數的情況下對數據進行聚合計算和分析 SELECT employee_name,department,salary,RANK() OVER (PARTITION BY department ORDER…

【機器學習基礎 4】 Pandas庫

一、Pandas庫簡介 Pandas 是一個開源的 Python 數據分析庫&#xff0c;主要用于數據清洗、處理、探索與分析。其核心數據結構是 Series&#xff08;一維數據&#xff09;和 DataFrame&#xff08;二維表格數據&#xff09;&#xff0c;可以讓我們高效地操作結構化數據。Pandas …

ETCD --- ?租約(Lease)?詳解

一、租約的核心概念 1. ?租約(Lease)? 一個租約是一個有時間限制的“授權”,綁定到鍵值對上。每個租約有一個唯一的ID(64位整數),通過etcdctl或客戶端API創建。創建租約時需指定TTL(Time-To-Live),即租約的有效期(單位:秒)。客戶端需定期向etcd發送續約(KeepAl…

33.[前端開發-JavaScript基礎]Day10-常見事件-鼠標事件-鍵盤事件-定時器-案例

1 window定時器 window定時器方法 setTimeout的使用 setInterval的使用 2 輪播消息提示 案例實戰一 – 輪播消息提示 3 關閉隱藏消息 案例實戰二 – 關閉隱藏消息 4 側邊欄展示 案例實戰三 – 側邊欄展示 5 tab切換實現 案例實戰四 – 登錄框&#xff08;作業&#xff09;…

react ant design樹穿梭框實現搜索并展開到子節點、同級節點選擇及同時選擇數量限制功能

功能點&#xff1a; 點擊節點前的箭頭&#xff0c;可以手動展開或折疊該節點的子節點。在搜索框中輸入關鍵詞&#xff0c;匹配的節點及其父節點會自動展開。清空搜索框后&#xff0c;恢復到用戶手動控制的展開狀態。勾選節點時仍然遵守 "最多勾選 6 個節點" 和 &quo…

阿里云云效 Maven

阿里云云效 Maven 官網&#xff1a;https://developer.aliyun.com/mvn/guide 阿里云Maven中央倉庫為 阿里云云效 提供的公共代理倉庫&#xff0c;幫助研發人員提高研發生產效率&#xff0c;使用阿里云Maven中央倉庫作為下載源&#xff0c;速度更快更穩定。 阿里云云效 是企業…

Go 語言標準庫中Channels,Goroutines詳細功能介紹與示例

在 Go 語言中&#xff0c;Goroutines&#xff08;協程&#xff09;和 Channels&#xff08;通道&#xff09;是并發編程的核心組件。它們共同協作&#xff0c;簡化了并發任務的管理和數據同步。以下通過詳細示例說明它們的用法和常見模式。 1. Goroutines&#xff08;協程&…

如何在 Postman 中正確設置 Session 以維持用戶狀態?

在 Postman 里面設置有 session 的請求。如果你還不知道什么是 session&#xff0c;那么請看這里—— session 是一種記錄客戶端和服務器之間狀態的機制&#xff0c;用于保持用戶的登錄狀態或者其他數據&#xff0c;從而讓用戶在不同頁面之間保持一致的體驗。 Postman 設置帶 …

DQN與PPO在算法層面的核心區別

DQN與PPO在算法層面的核心區別 1. 學習目標不同 DQN(基于價值): 核心:學習動作價值函數 Q ( s , a ) Q(s, a)

Linux: 網絡,arp的數量為什么會對交換機/路由器有性能的影響

這個問題也是非常普遍的問題。比如最近比較火的一個OVS相關的問題: ARP request packets put high pressure on the pinctrl thread in ovn-controller 另一個在工作種也遇到了相似的問題,當一個網絡里發了同時發了小一百個GARP之后,路由器的gateway就會有ARP處理延遲。 A…

解析 HTML 網站架構規范

2025/3/28 向全棧工程師邁進&#xff01; 一、網頁基本的組成部分 網頁的外觀多種多樣&#xff0c;但是除了全屏視頻或游戲&#xff0c;或藝術作品頁面&#xff0c;或只是結構不當的頁面以外&#xff0c;都傾向于使用類似的標準組件。 1.1頁眉 通常橫跨于整個頁面頂部有一…

Golang 當中 byte 和 rune 類型的區別

文章目錄 Golang 當中 byte 和 rune 類型的區別類型定義與用途字符串處理差異內存占用典型引用場景 Golang 當中 byte 和 rune 類型的區別 在 Golang 中&#xff0c;rune 和 byte 類型的區別主要體現在字符處理的方式和編碼支持上。 類型定義與用途 byte 類型 本質是 uint8…

vue將頁面導出成word

方法一&#xff1a;使用 html-docx-js html-docx-js 是一個輕量級的庫&#xff0c;可以將 HTML 轉換為 Word 文檔。 安裝依賴 首先安裝 html-docx-js&#xff1a; Bash深色版本 npm install html-docx-js --save創建導出邏輯 在 Vue 組件中實現導出功能的代碼如下&#xff1…

Three.js 快速入門教程【二十】3D模型加載優化實戰:使用gltf-pipeline與Draco對模型進行壓縮,提高加載速度和流暢性

系列文章目錄 Three.js 快速入門教程【一】開啟你的 3D Web 開發之旅 Three.js 快速入門教程【二】透視投影相機 Three.js 快速入門教程【三】渲染器 Three.js 快速入門教程【四】三維坐標系 Three.js 快速入門教程【五】動畫渲染循環 Three.js 快速入門教程【六】相機控件 Or…

前端框架入門:Angular

Angular 是由 Google 維護的前端框架,適用于構建單頁應用(SPA)。它使用TypeScript 作為主要開發語言,并提供了強大的模塊化、依賴注入(DI)、路由管理等特性。 一、Angular 基礎 1. Angular 介紹 Angular 是一個組件化、模塊化、雙向數據綁定的前端框架,適用于構建復雜…

基于51單片機的速度檢測報警器proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1I7roZEjrk349Is_YdMcsxQ 提取碼&#xff1a;1234 仿真圖&#xff1a; 芯片/模塊的特點&#xff1a; AT89C52/AT89C51簡介&#xff1a; AT89C51 是一款常用的 8 位單片機&#xff0c;由 Atmel 公司&#xff08;現已被 Microchip 收…

具身系列——Diffusion Policy算法實現CartPole游戲

代碼原理分析 1. 核心思想 該代碼實現了一個基于擴散模型&#xff08;Diffusion Model&#xff09;的強化學習策略網絡。擴散模型通過逐步去噪過程生成動作&#xff0c;核心思想是&#xff1a; ? 前向過程&#xff1a;通過T步逐漸將專家動作添加高斯噪聲&#xff0c;最終變成…

DeepSeek 本地化部署教程

1 概述 1.1 配置參考圖 科普&#xff1a; B&#xff0c;Billion&#xff08;十億&#xff09;&#xff0c;是 “參數量” 的單位。 模型量超過 一億&#xff0c;可稱之為 “大模型”。 2 軟件安裝 2.1 下載 Ollama 官方主頁&#xff1a;https://ollama.com/download主頁截圖…

matlab打開兩個工程

1、問題描述 寫代碼時&#xff0c;需要實時參考別人的代碼&#xff0c;需要同時打開2個模型&#xff0c;當模型在同一個工程內時&#xff0c;這是可以直接打開的&#xff0c;如圖所示 2、解決方案 再打開一個MATLAB主窗口 這個時候就可以同時打開多個模型了 3、正確的打開方…

mac 下配置flutter 總是失敗,請參考文章重新配置flutter 環境MacOS Flutter環境配置和安裝

一、安裝和運行Flutter的系統環境要求 想要安裝并運行 Flutter&#xff0c;你的開發環境需要最低滿足以下要求&#xff1a; 操作系統:macOS磁盤空間:2.8 GB(不包括IDE/tools的磁盤空間)。工具:Flutter使用git進行安裝和升級。我們建議安裝Xcode&#xff0c;其中包括git&#x…