這幾天在研究JAVA反射,分享一下心得:
JAVA反射基本的包括:
(1):怎么獲取字節(jié)碼
(2):怎么獲取構(gòu)造器
(3):怎么調(diào)用構(gòu)造器
(4):怎么獲取方法
(5):怎么調(diào)用方法
(6):怎么獲取字段
(7):怎么操作字段
(8):怎么獲取泛型參數(shù)信息
接下來我就一個一個在講一下實例
(1).怎么獲取字節(jié)碼:
獲取字節(jié)碼有3種方法
方法一: 類名.Class;
Class cla =User.Class;
方法二:Class.forName("全限類名");
Class cla = Class.forName("Day_03.User");
注:全限類名就是包名+類名;
方法三:new 類名().getClass ;
Class cla = new User().getClass;
(2): 怎么獲取構(gòu)造器
思想:
(1)明確操作的是哪一份字節(jié)碼對象
(2)獲取構(gòu)造器
獲取構(gòu)造器的方法:
1. 獲取類中所有的構(gòu)造器
public Constuctor<?>[] getConstuctors(): 該方法只能獲取當(dāng)前Class所表示類的public修飾的構(gòu)造器
public Constuctor<?>[] getDeclaredConstuctors(): 該方法獲取當(dāng)前Class所表示類的所有的構(gòu)造器,和訪問權(quán)限無
2. 獲取指定的一個構(gòu)造器
public Constructor<T> getConstructor(Class<?>... parameterTypes): 該方法獲取當(dāng)前Class所表示類中指定的一個public修飾的構(gòu)造器
參數(shù) parameterTypes表示:構(gòu)造器參數(shù)的Class類型
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 該方法獲取當(dāng)前Class所表示類中指定的一個構(gòu)造器,和訪問權(quán)限無關(guān)
參數(shù) parameterTypes表示:構(gòu)造器參數(shù)的Class類型
(3):怎么調(diào)用構(gòu)造器
思想:
(1)先找到被調(diào)用構(gòu)造器所在類的字節(jié)碼
(2) 找到被調(diào)用的構(gòu)造器
(3) 執(zhí)行該構(gòu)造器,調(diào)用構(gòu)造器
注意 : 如果該構(gòu)造器的修飾符是私有的,如果硬要訪問,則在調(diào)用構(gòu)造器之前調(diào)用public void setAccessible(boolean flag)方法
將setAccessible(true)設(shè)置可訪問的就行了
例子 private User(String name,int age){
System.out.print("name"+name+","+"age"+age);
}
Class arr1 = User.class;
Constructor<User> b = arr1.getDeclaredConstructor(String.class,int.class);
System.out.println(b);
b.setAccessible(true);
User ca = b.newInstance("wei", 17);
(4):怎么獲取方法
思想
(1)找到獲取方法所在類中的字節(jié)碼對象
(2)找到需要被獲取的方法
獲取方法的方法
1. 獲取類中所有的方法
public Method[] getMethods(): 獲取包括自身和繼承過來的所有的public方法
public Method[] getDeclaredMethods():獲取自身所有的方法(不包括繼承的,和訪問權(quán)限無關(guān))
2.獲取類中指定的方法
public Method getMethod(String name,Class<?>... parameterTypes):表示調(diào)用指定的一個公共的方法(包括繼承的)
參數(shù):
name:表示被調(diào)用方法的名字
parameterTypes:表示被調(diào)用方法的參數(shù)的Class類型如String.class
public Method getDeclaredMethod(String name, Class<?>... parameterTypes):表示調(diào)用指定的一個本類中的一個方法(不包括繼承的)
參數(shù):
name:表示被調(diào)用方法的名字
parameterTypes:表示被調(diào)用方法的參數(shù)的Class類型如String.class
(5):怎么調(diào)用方法
思想:
(1)找到被調(diào)用方法所在的字節(jié)碼
(2)獲取到被調(diào)用的方法對象
(3)調(diào)用該方法
如何使用反射調(diào)用一個方法:
在Method類中有方法
public Object invoke(Object obj, Object... args):表示調(diào)用當(dāng)前Method所表示的方法
參數(shù):
obj:表示被調(diào)用方法底層所屬對象
args:表示調(diào)用方法是傳遞的實際參數(shù)
返回值:
底層方法的返回結(jié)果
注意:
1.在調(diào)用私有方法:
在調(diào)用私有方法之前:應(yīng)該設(shè)置該方法是可訪問的,又因為Method是AccessibleObject子類,所以Method中具有該方法.
將setAccessible(true)設(shè)置可訪問的就行了
2.使用反射調(diào)用靜態(tài)方法
public Object invoke(Object obj, Object... args)
如果底層方法是靜態(tài)的,那么可以忽略指定的obj參數(shù),將obj參數(shù)設(shè)置為null即可.
(6):怎么獲取字段
思想:
(1).找到字段所在類的字節(jié)碼對象
(2) 獲取字段
獲取字段的方法
1.獲取所有的字段
public Field[] getFields():獲取當(dāng)前Class所表示類中的所有的public字段,包括繼承的字段.
public Field[] getDeclaredFields():獲取當(dāng)前Class所表示類中的所有的字段,不包括繼承的字段.
2.獲取指定的字段
public Field getDeclaredField(String name):獲取當(dāng)前Class所表示類中指定的一個public字段,包括繼承的字段.
public Field getField(String name):獲取當(dāng)前Class所表示類中指定的一個字段,不包括繼承的字段.
(7):怎么操作字段
思想:
(1)找到被操作字段所在類的字節(jié)碼
(2)獲取到該被操作的字段對象
(3)設(shè)置值/獲取值
注意:
在調(diào)用私有字段:
在調(diào)用私有字段之前:應(yīng)該設(shè)置該字段是可訪問的,又因為Filed是AccessibleObject子類,所以Filed中具有該方法.
setAccible(true)
Filed類常用方法:
(1)設(shè)置值
void setXX( Object obj,XX value):表示為基本類型數(shù)據(jù)字段設(shè)置值 XX表示基本數(shù)據(jù)類型
void set(Object obj,Objcet value):表示為引用類型數(shù)據(jù)字段設(shè)置值
參數(shù):
obj:表示字段底層所屬對象,若該字段是static的,該值可以設(shè)置為null
value:表示將要設(shè)置的值
(2)獲取值
XX getXX( Object obj):表示獲取基本類型數(shù)據(jù)字段的值 XX表示基本數(shù)據(jù)類型
Object get(Object obj):表示獲取引用類型數(shù)據(jù)字段的值
參數(shù):
obj:表示字段底層所屬對象,若該字段是static的,該值可以設(shè)置為null
返回值:
返回該字段的值
(8):怎么獲取泛型參數(shù)信息
思想;
(1)獲取泛型所在字節(jié)碼對象
(2)獲取字段
(3)通過getGenericType()方法獲取Type類型(該對象包含了泛型信息)
(4)將getGenericType()返回的類型強轉(zhuǎn)成ParameterizedType類型
(5)調(diào)用ParameterizedType中的Type[] getActualTypeArguments()方法
(6)Type[]中就保存了泛型信息
例子:
Class<User> arr = User.class;
Field ass = arr.getField("ap");
java.lang.reflect.Type type = ass.getGenericType();
ParameterizedType asda = (ParameterizedType) type;
java.lang.reflect.Type[] gg = asda.getActualTypeArguments();
System.out.println(Arrays.toString(gg));
學(xué)習(xí)Java的同學(xué)注意了!??!
學(xué)習(xí)過程中遇到什么問題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群346942462,我們一起學(xué)Java!