Java核心技術筆記——第 12 章 反射

轉載自:[https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html]

12 反射

1. 引入反射

通常情況下,調用一個類的方法的步驟如下:

  1. 創建該類的對象。
  2. 調用該對象的方法。

通過這種方式調用方法時,必須要知道類的定義以及類的所有屬性和方法。代碼如下:

Apple apple = new Apple(); //直接初始化,「正射」
apple.setPrice(4);

另一種調用類方法的方式是:反射。示例如下:

//獲取類的class對象
Class clz = Class.forName("com.chenshuyi.reflect.Apple");
//獲取類的指定方法的method對象
Method method = clz.getMethod("setPrice", int.class);
//獲取類的默認構造器
Constructor constructor = clz.getConstructor();
//創建類的對象
Object object = constructor.newInstance();
//調用方法
method.invoke(object, 4);

上面兩段代碼的執行結果,其實是完全一樣的。但是其思路完全不一樣,第一段代碼在未運行時就已經確定了要運行的類(Apple),而第二段代碼則是在運行時通過字符串值才得知要運行的類(com.chenshuyi.reflect.Apple)。

2. 反射定義

反射就是在運行時才知道要操作的類是什么,并且可以在運行時獲取類的完整構造,并調用對應的方法。

3. 示例的完整代碼

public class Apple {private int price;public int getPrice(){return price;}public void setPrice(int price) {this.price = price;}public static void main(String[] args) throws Exception{//正常的調用Apple apple = new Apple();apple.setPrice(5);System.out.println("Apple Price:" + apple.getPrice());//使用反射調用Class clz = Class.forName("com.chenshuyi.api.Apple");Method setPriceMethod = clz.getMethod("setPrice", int.class);Constructor appleConstructor = clz.getConstructor();Object appleObj = appleConstructor.newInstance();setPriceMethod.invoke(appleObj, 14);Method getPriceMethod = clz.getMethod("getPrice");System.out.println("Apple Price:" + getPriceMethod.invoke(appleObj));}
}

4. 反射調用的步驟

一般情況下我們使用反射獲取一個對象的步驟:

  1. 獲取類的 Class 對象實例

    Class clz = Class.forName("com.zhenai.api.Apple");
  2. 根據 Class 對象實例獲取 Constructor 對象

    Constructor appleConstructor = clz.getConstructor();
  3. 使用 Constructor 對象的 newInstance 方法獲取反射類對象

    Object appleObj = appleConstructor.newInstance();

如果要調用某一個方法,則需要經過下面的步驟:

  1. 獲取方法的 Method 對象

    Method setPriceMethod = clz.getMethod("setPrice", int.class);
  2. 利用 invoke 方法調用方法

    setPriceMethod.invoke(appleObj, 14);

5. 反射常用的 API

1. 獲取反射中的 Class 對象

在反射中,要獲取一個類或調用一個類的方法,我們首先需要獲取到該類的 Class 對象。在 Java API 中,獲取 Class 類對象有三種方法:

  • 使用 Class.forName 靜態方法。當你知道類的全路徑名時,你可以使用該方法獲取 Class 類對象。

    Class clz = Class.forName("java.lang.String"); 
  • 使用 類型名.class 。

    Class clz = String.class;
  • 使用類對象的 getClass() 方法。

    String str = new String("Hello");
    Class clz = str.getClass();

2. 通過反射創建類對象

通過反射創建類對象主要有兩種方式(newInstance() 的返回值是 Object):

  • 通過 Class 對象的 newInstance() 方法

    Class clz = Apple.class;
    Apple apple = (Apple)clz.newInstance();
  • 通過 Constructor 對象的 newInstance() 方法。

    Class clz = Apple.class;
    Constructor constructor = clz.getConstructor();
    Apple apple = (Apple)constructor.newInstance();

通過 Constructor 對象創建類對象可以選擇特定構造方法,而通過 Class 對象則只能使用默認的無參數構造方法。下面的代碼就調用了一個有參數的構造方法進行了類對象的初始化:

Class clz = Apple.class;
Constructor constructor = clz.getConstructor(String.class, int.class);
Apple apple = (Apple)constructor.newInstance("紅富士", 15);

3. 通過反射獲取類屬性、方法、構造器

獲取類的屬性

  • Field getField(String name):獲取 Class 對象對應類的指定公有屬性。
  • Field[] getFields():獲取 Class 對象對應類的所有公有屬性(包括從父類中繼承的公有屬性),無法獲取類的私有屬性。
  • Field[] getDeclaredFields():獲取 Class 對象對應類的所有屬性(僅限本類中定義的公有、默認、保護、私有屬性,不包括從父類中繼承的屬性)。
  • Field getDeclaredField(String name):獲取 Class 對象對應類的指定屬性(僅限本類中定義的公有或默認或保護或私有屬性,不包括從父類中繼承的屬性)。

獲取類的方法

  • Method getMethod(String name, Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有方法。
  • Method[] getMethods(): 獲取 Class 對象對應類的所有公有方法(包括從父類中繼承的公有方法),無法獲取類的私有方法。
  • Method[] getDeclaredMethods():獲取 Class 對象對應類的所有方法(僅限本類中定義的公有、默認、保護、私有方法,不包括從父類中繼承的方法,以及本類的構造器)。
  • Method getDeclaredMethod(String name, Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有方法(僅限本類中定義的公有或默認或保護或私有方法,不包括從父類中繼承的方法)。

獲取類的構造器

  • Constructor<T> getConstructor(Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有構造器。
  • Constructor<?>[] getConstructors():獲取 Class 對象對應類的所有公有構造器。
  • Constructor<?>[] getDeclaredConstructors():獲取 Class 對象對應類的所有構造器。
  • Constructor<?>[] getDeclaredConstructor(Class<?>... parameterTypes):獲取 Class 對象對應類的指定構造器(公有或私有)。

轉載于:https://www.cnblogs.com/echie/p/9785676.html

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

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

相關文章

HTML5知識點匯總

1、HTML5新特性 用于繪畫的canvas標簽用于媒介回放的video和audio元素對本地離線儲存的更好支持新的特殊內容元素&#xff0c;如&#xff1a;article、footer、header、nav、section、aside、hgroup、figure新的表單控件&#xff0c;如&#xff1a;calendar、date、time、emai…

實用網站

https://blog.csdn.net/devcloud/article/details/103121883

網絡(圖)(數學)

轉載于:https://www.cnblogs.com/fengxunling/p/9781575.html

DES加解密時 Given final block not properly padded 的解決方案

事情的經過是這個樣子的。。。。。。 先說說問題是怎么出現的。根據客戶需求&#xff0c;需要完成一個一鍵登錄的功能&#xff0c;于是我的項目中就誕生了DesUtil&#xff0c;但是經過幾百次測試&#xff0c;發現有一個登錄直接報錯&#xff01;難道又遇到神坑啦&#xff01;&a…

java 算法優化向導

一.什么是數據結構&#xff1f;什么是算法 不必像學生時代深究定義。以一個簡單的例子說明。 數據結構&#xff0c;圖書館的書怎么擺列&#xff0c;按照書的類型&#xff0c;作者&#xff0c;出版時間&#xff0c;語言等等放置&#xff0c;這就是數據的結構。 算法&#xff0c…

appium工作原理

Appium原理 面試的時候&#xff0c;被問到appium原理&#xff0c;一點不會&#xff0c;實在尷尬。大家可以直接翻看原作https://blog.csdn.net/jffhy2017/article/details/69220719 appium運行時安裝的2個應用&#xff1a;Appium Settings和Unlock。 一、appium加載的過程圖解&…

LeetCode 21. Merge Two Sorted Lists

LeetCode 21. Merge Two Sorted Lists 分析 難度&#xff1a;易 題目 Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. Example: Input: 1->2->4, 1->3->4 Out…

Mac OS X 下 TAR.GZ 方式安裝 MySQL

Mac OS X 下 TAR.GZ 方式安裝 MySQL 注意: 本篇文章適用與 MySQL 5.6 版本的安裝, 但已不再適用 5.7 的安裝, 5.7 的安裝方式請參見:《Mac OS X 下 TAR.GZ 方式安裝 MySQL 5.7》 在 Mac 系統上, 安裝 MySQL Server 一般是用 DMG 包在圖形化界面下按提示安裝, 此外 MySQL 還提供…

快排再改進

快排再改進 #include <iostream> using namespace std;void mySwap(int &a, int &b) {int temp a;a b;b temp; }void insertSort(int a[], int left, int right) {int tmp;int in 0;int out 0;for (out left 1; out < right; out) {tmp a[out];in ou…

【Linux基礎】crontab定時命令詳解

周期執行的任務一般由cron這個守護進程來處理[ps -ef|grep cron]。cron讀取一個或多個配置文件&#xff0c;這些配置文件中包含了命令行及其調用時間。cron的配置文件稱為“crontab”&#xff0c;是“cron table”的簡寫。 一、cron服務  cron是一個linux下 的定時執行工具&a…

5個Vue.js項目的令人敬畏的模板

開發人員查看使用SPA&#xff0c;Webpack&#xff0c;身份驗證&#xff0c;GraphQL&#xff0c;文檔和測試的Vue開發人員的資源。 你準備開始一個重要的Vue項目嗎&#xff1f;為了確保從堅實的基礎開始&#xff0c;您可以使用模板&#xff08;也就是樣板&#xff0c;骨架&#…

測試多個輸入條件的方法

轉載于:https://www.cnblogs.com/www-qcdwx-com/p/10641281.html

問題規模

問題規模本身并沒有非常精準的定義吧一般都是指運行時間t和輸入參數個數n的關系用O(n)表示比如max([x])就是O(n)而冒泡排序則是O(n^2)

SSM+mybatis單元測試

初學SSMmybatis單元測試遇到的問題&#xff0c;dao注入后為nullDao層注入失敗&#xff0c;查看后&#xff0c;發現注解都寫的無誤&#xff0c;經朋友的指點&#xff0c;在測試類上加了一句“RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(locations{“classpat…

Sublime text 2/3 中 Package Control 的安裝與使用方法

Package Control 插件是一個方便 Sublime text 管理插件的插件&#xff0c;但因為 Sublime Text 3 更新了 Python 的函數&#xff0c;API不同了&#xff0c;導致基于 Python 開發的插件很多都不能工作&#xff0c;Package Control 原來的安裝方法都失效了。 網上有2種使用 Git…

接口測試

集成&#xff1a; 接口&#xff0c;代碼級&#xff0c;service層 unit-》service-》UI 接口測試和界面沒有任何關系 A->B  數據流向 理論 我們學過&#xff0c;集成測試主要測接口&#xff0c;通過學習集成測試&#xff0c;我們發現是把單元測試通過后的方法直接需要對接的…

React-Router ---withRouter

import React from react import { withRouter } from react-router const Hello (props) > { return ( <div><button onClick{ () > props.history.push(/about) }>Hello</button></div> ) } const WithRouterHello withRouter(Hello);//也可…

vue從入門到精通之進階篇(一)vue-router基礎

路由原理 傳統開發方式 url改變后 立刻發起請求&#xff0c;響應整個頁面&#xff0c;渲染整個頁面SPA 錨點值改變后 不會發起請求,發起ajax請求,局部改變頁面數據 頁面不跳轉 用戶體驗更好 SPA single page application(單頁應用程序)前端路由 錨點值監視ajax獲取動態數據…

自動計算請假工時 排除周六周日

/*** 請假工時計算* starttime 開始時間 "2019-03-28 16:02", endtime 結束時間 "2019-03-29 16:02"*/ function leaveTime(starttime, endtime) {var start new Date(starttime); //start Thu Mar 28 2019 16:02:00 GMT0800 (中國標準時間)var end new…

垃圾回收與內存管理

垃圾回收機制 Javascript采用 自動垃圾收集機制&#xff0c;執行環境會負責跟蹤代碼執行過程中使用的內存&#xff0c;而在C和C類的語言中&#xff0c;需要開發人員手工跟蹤內存的使用情況。 該機制的實現原理&#xff1a;找出那些不再繼續使用的變量&#xff0c;然后釋放其占用…