黑馬程序員-Java基礎-反射

第一講 反射應用場景&特色函數

一、反射定義3d

動態的獲取指定類以及動態的調用類中的內容。給程序使用者提供了一個能夠本身定製功能的接口,提升了程序的擴展性。對象

二、實現方式blog

經過配置文件的方式,程序使用者在配置文件中設置自定義的類名,程序內部調用該配置文件,獲取該類的字節碼文件及類對象,進而調用類中的成員方法和成員變量,實現了成語與使用者的交互。接口

其中,實現接口的類由程序使用者本身定義。字符串

三、圖解示例get

           

 

 

 

 

 

第二講 獲取字節碼文件對象&建立類對象it

一、Class類ast

Class——用來描述字節碼文件的類,反射的技術就是經過該類來實現的。class

該類中提供和獲取類字節碼文件對應類中的構造函數對象、通常方法對象、字段對象的方法。

二、獲取字節碼文件的對象的方式

方式一:經過Object類中的getClass()方法獲取,須要經過類的對象調用。

示例以下:獲取Person類中的字節碼文件對象

Person p = new Person();——建立類對象

Class clazz = p.getClass();——經過Object中的方法getClass()獲取字節碼文件對象。

說明:這種方法須要明確具體的類,並建立該類的對象,比較麻煩。

方式二:任何數據類型都具有一個靜態的屬性」.class」,能夠用類直接調用:Class clazz = Person.class;

說明:該方法相對於方式一更加簡單,但仍是要明確類名和類中的靜態成員,仍是不夠擴展。

方式三:Class類中的forName(String className)方法,其中的className要完整,包括包名(如,cn.itcast.bean.Person)。

代碼實現以下:

String className = 「cn.itcast.bean.Person」;——這裏的類型能夠經過配置文件讀取到,由程序使用者本身定義類,並將類型輸入到配置文件指定位置,傳入程序中。

Class clazz = forName(className);——程序經過從配置文件上獲取到的類名來獲取該類對應的字節碼文件對象。

說明:只經過給定的類的字符串名稱就能夠獲取該類,擴展性更強。

以上三種方式代碼示例:

 

 

第三講 獲取構造函數&動態建立類對象

一、概述

要建立類對象就須要調用類的構造函數(類內部定義方法獲取對象的狀況除外),Class類中定義了獲取類對象的方法newInstance(),該方法調用了類中的無參數構造函數;

代碼實現以下:

 

二、調用類中有參數構造函數來建立類對象

Class類中的newInstance()方法只能調用類中的無參數構造函數,要想經過類中的有參數構造函數來建立類對象,就要先獲取類中的有參數構造函數。

實現方法:

先獲取類中帶參數的構造函數對象(利用

getConstructor(String.class,int.class)方法),根據本身須要來肯定參數列表;

而後經過獲取到的構造函數對象調用方法newInstance(String str,int i),來調用類中帶參數構造函數來建立類對象,代碼實現以下:

 

 

 

 

第四講  獲取類中的方法

一、概述

咱們獲取到類的字節碼文件對象後,能夠經過該對象獲取中通常方法的對象,而後用方法對象獲取通常方法。

二、獲取並調用通常方法

  • 獲取字節文件對象;

Class clazz = Class.forName(className);

  • 根據方法名獲取方法對象;

Method method = clazz.getMethod(methodName,String.class,int.class);

取空參數函數:clazz.getMethod(methodName,null)

  • 調用方法;

Object obj = clazz.newInstance();——需先建立類對象。

methods.invoke(obj,」zhangsan」,」23」);

調用靜態方法:methods.invoke(null,」zhangsan」,」23」);——調用靜態方法,不須要對象。

       總結:經過字節碼文件對象來獲取方法對象,經過方法類中的invoke()來調用方法。若是調用的是非靜態方法,則invoke()實際參數中要有類對象;若,調用的是靜態方法,則不須要類對象,用null代替。沒有參數的地方,用null代替。

 

 

第五講 獲取字段&暴力訪問

一、概述

Class類中定義了獲取字段對象的方法,獲取了字段對象,就能夠用它來訪問類中的字段(獲取、設置等)。

二、獲取並設置字段步驟

  • 獲取字節碼文件對象;——Class.forName()
  • 用字節碼文件對象調用Class中的方法getField(fieldName)或

getDeclaredField(fieldName)來獲取自定名稱的字段對象;

getField(fieldName)——獲取的是共有字段的對象;

getDeclaredField(fieldName)——獲取的是因此字段的對象;

  • 設置字段;——field.set(obj,90);須要指定類對象。

說明:若爲私有字段,此處設置字段值會失敗,咱們能夠經過暴力訪問的方式,將訪問權限檢查取消,再設置字段的值。

三、暴力訪問類中的私有成員——用AccessiableObject類

定義:AccessiableObject類是Field類、Method類、Constructor類的父類,該類中方法setAccessible()能夠取消類中成員的權限檢查,以使得Field類對象、Method類對象、Constructor類對象可以訪問類中的私有字段、方法;

實現代碼:

Field.setAccessible(true);——取消對字段的的權限訪問,即暴力訪問。

field.set(obj,90);——設置私有字段值。

 

說明:程序將成員聲明成私有的,試想把該成員保護起來,因此通常不訪問私有成員。

 

 

 

第六講   反射應用案例

演示筆記本電腦使用USB接口示例:

需求:筆記本電腦調用接入USB接口的設備,要求不一樣的設備執行不一樣的方法。

思路

一、電腦須要使用一些外圍設備,如鼠標、鍵盤、U盤等,爲了提升擴展性,應該下降這些設備和電腦的耦合性,所以就須要引入接口的技術(無論接入什麼設備,只要符合USB規則,就能夠被電腦使用)。

二、然而,若是USB接口接入了新的設備,就須要修改原始代碼,才能調用新的設備,這樣很麻煩,所以,能夠引入反射的技術,提供一個配置文件。

三、咱們只須要將接入設備的功能定義好,而且在配置文件中傳入設備的信息,在不修改原代碼的狀況下,電腦也能使用接入的設備。

代碼演示:

 

相關文章
相關標籤/搜索