反射方法 的簡單使用
獲得字節碼文件對象的三種方式
首先第一句,一切皆對象。類、屬性、方法、構造器都是對象
該篇文章其實就注重兩個點、是否有declared前綴,帶有private的記得調用setAccessible
所涉及到的類:Class、Field、Construcotr、Method
-
Object類的getClass方法
-
類型.class 屬性
-
Class.forName(“類的路徑”)
都爲true,內存地址是一樣的。在程序的運行中,Person的class文件只被加載了一次。
也爲true,可知只加載了一次
也爲true
用字節碼文件對象來構建一個類的對象
字節碼文件對象中包含:
那麼 這4個 在 字節碼文件對象中叫什麼呢?
java文件 | 字節碼文件 |
---|---|
類 | 字節碼文件對象 |
構造方法 | 構造方法對象(類型Constructor) |
成員變量 | 成員變量對象(類型Field) |
成員方法 | 成員方法(類型Method) |
之前一直用new的形式來創建一個類的對象
Person p = new Person()
加粗部分是類的構造方法,因爲對象是通過構造方法創建的
用字節碼文件中的構造器對象來創建一個類的對象——Constructor對象
獲得Constructor來創建對象
注意:getDeclaredConstructor(Class<?>… parameterTypes)
這個方法會返回指定參數類型的所有構造器,**包括public的和非public的,**當然也包括private的。
getDeclaredConstructors()的返回結果就沒有參數類型的過濾了。
再來看getConstructor(Class<?>… parameterTypes)
這個方法返回的是上面那個方法返回結果的子集,只返回制定參數類型訪問權限是public的構造器。
getConstructors()的返回結果同樣也沒有參數類型的過濾。
用反射有什麼好處呢?之前Spring ioc有講。可以通過配置文件動態創建對象:
來:
創建一個a.txt用來存儲要創建對象的 全路徑名稱,之後讀取這個字符串,用class.forName創建就可以了。以Person爲例
獲取名稱後也可創建對象。
構造方法對象
四個訪問修飾符:
getConstrustors是獲取公有的,所以只有一個
getDeclaredConstructors這個就是得到所有的
獲取指定的構造器
這是public的,如果不是public,使用getConstructor獲得指定方法機會報NoSuchMethodException
所以也是用帶Declared的getDeclaredConstructor
那麼其他訪問修飾符呢?
私有的可以得到構造器,但是不能創建對象
通過constructor.setAccessible(true)設置爲可以訪問
方法對象
它也有這些
其他方法是因爲還有Object的,當然這是public的,要所有的需要加上Declared
先給Person加上getter與setter,以及該類的一個私有方法
可以發現有以下的區別
1.不帶declared是得到所有的public修飾的method 包括從父類繼承過來的Declared
2.帶declared是得到當前類中的所有Method
注意,getMethod()是得到公有的方法,同樣的也有getDeclaredMethod()
同樣的,如果將getName()這個方法的訪問權限改爲私有的,那麼也將報 **IllegalAccessException **
那麼也是一樣的,需要設置一下
得到屬性對象
getField跟getDeclaredField,跟上面的一樣的。因爲這裏是private