反射方法 的簡單使用

反射方法 的簡單使用

獲得字節碼文件對象的三種方式

首先第一句,一切皆對象。類、屬性、方法、構造器都是對象

該篇文章其實就注重兩個點、是否有declared前綴,帶有private的記得調用setAccessible
所涉及到的類:Class、Field、Construcotr、Method

  1. Object類的getClass方法

  2. 類型.class 屬性

  3. Class.forName(“類的路徑”)

    image-20200607161433834

都爲true,內存地址是一樣的。在程序的運行中,Person的class文件只被加載了一次。

image-20200607161626586

也爲true,可知只加載了一次

image-20200607161907591

也爲true

用字節碼文件對象來構建一個類的對象

image-20200607162932098

字節碼文件對象中包含:

那麼 這4個字節碼文件對象中叫什麼呢?

java文件 字節碼文件
字節碼文件對象
構造方法 構造方法對象(類型Constructor)
成員變量 成員變量對象(類型Field)
成員方法 成員方法(類型Method)

之前一直用new的形式來創建一個類的對象

Person p = new Person()

加粗部分是類的構造方法,因爲對象是通過構造方法創建的

用字節碼文件中的構造器對象來創建一個類的對象——Constructor對象

image-20200607165151665

獲得Constructor來創建對象

注意:getDeclaredConstructor(Class<?>… parameterTypes)
這個方法會返回指定參數類型的所有構造器,**包括public的和非public的,**當然也包括private的。
getDeclaredConstructors()的返回結果就沒有參數類型的過濾了。

再來看getConstructor(Class<?>… parameterTypes)
這個方法返回的是上面那個方法返回結果的子集,只返回制定參數類型訪問權限是public的構造器。
getConstructors()的返回結果同樣也沒有參數類型的過濾。

用反射有什麼好處呢?之前Spring ioc有講。可以通過配置文件動態創建對象:

來:

創建一個a.txt用來存儲要創建對象的 全路徑名稱,之後讀取這個字符串,用class.forName創建就可以了。以Person爲例

image-20200607165644004

獲取名稱後也可創建對象。

構造方法對象

四個訪問修飾符:

image-20200607171458965

image-20200607174759323

getConstrustors是獲取公有的,所以只有一個

image-20200607174902268

getDeclaredConstructors這個就是得到所有的

獲取指定的構造器

image-20200607175158291

這是public的,如果不是public,使用getConstructor獲得指定方法機會報NoSuchMethodException

image-20200607175310534

所以也是用帶Declared的getDeclaredConstructor

那麼其他訪問修飾符呢?

image-20200607180232347

私有的可以得到構造器,但是不能創建對象

image-20200607180338222

通過constructor.setAccessible(true)設置爲可以訪問

方法對象

它也有這些

image-20200607180610378

image-20200607180641434

其他方法是因爲還有Object的,當然這是public的,要所有的需要加上Declared

先給Person加上getter與setter,以及該類的一個私有方法

image-20200607181104007

image-20200607181124194

可以發現有以下的區別

1.不帶declared是得到所有的public修飾的method 包括從父類繼承過來的Declared

2.帶declared是得到當前類中的所有Method

image-20200607183830023

注意,getMethod()是得到公有的方法,同樣的也有getDeclaredMethod()

同樣的,如果將getName()這個方法的訪問權限改爲私有的,那麼也將報 **IllegalAccessException **

image-20200607184211889

那麼也是一樣的,需要設置一下

image-20200607184320224

得到屬性對象

getField跟getDeclaredField,跟上面的一樣的。因爲這裏是private

image-20200607190400689

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章