文章目錄
- 反射是什么?
- 反射的作用
- 所有方法匯總
- 一、加載Class對象
- 二、加載類的構造器對象
- 三、加載類的成員變量
- 四、加載類的成員方法
反射是什么?
反射就是:加載類,并允許以編程的方式解剖類中的某個成分(成員變量,方法,構造器等)
反射需要學什么
- 反射第一步:加載類,獲取類的字節碼:Class對象
- 獲取類的構造器:Constructor對象
- 獲取類的成員變量:Field對象
- 獲取類的成員方法:Method對象
在反射中,最重要的就是Class對象,之后的一切操作都是根據Class對象來操作的
反射的作用
-
基本作用:可以得到一個類的全部成分然后操作
-
可以破壞封裝性
-
適合做Java的框架,主流的框架會基于反射設計出一些通用的功能
一下測試代碼我只提供了一個方法,需要源代碼的在這里:反射代碼
所有方法匯總
一、加載Class對象
獲取Class對象的三種方法
- Class c1 = 類名.class
- 調用Class提供方法:public static Class forName(String Package);
- Object提供的方法:public Class getClass(); Class c3 = 對象.getClass();
/*** 測試三種方式得到的Class的三種方法* @throws ClassNotFoundException*/@Testpublic void testEquals() throws ClassNotFoundException {Class s1 = Class.forName("com.wk.reflect.Student");Class s2 = Student.class;Student student = new Student();Class s3 = student.getClass();System.out.println(s1 == s2); //trueSystem.out.println(s2 == s3); //trueSystem.out.println(s1 == s3); //true}
二、加載類的構造器對象
加載構造器對象的步驟:
- 獲取類的Class對象
- 調用方法獲得構造器對象
- 使用:創建一個對象實例newInstance()
獲取構造器的方法如下
方法 | 說明 |
---|---|
Constructor<?>[] getConstructors() | 獲取全部構造器(只能獲取public修飾) |
Constructor<?>[] getDeclaredConstructors() | 獲取全部構造器(任意修飾都可以拿到) |
Constructor getConstructor(Class<?>… parameterTypes) | 獲取某個構造器(只能能獲取public修飾) |
Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 獲取某個構造器(任意修飾都可以拿到) |
Constructor提供的方法 | 說明 |
---|---|
T newInstance(Object… initargs | 調用此構造器對象表示的構造器,并傳入參數,完成對象的初始化并返回 |
public void setAccessible(boolean flag) | 設置為True,表示禁止加內存訪問控制(暴力反射) |
@Testpublic void testAll() throws Exception {//獲得一個Class對象Class<Student> s1 = Student.class;//獲取一個構造器//這里將無參構造器設置為private的,但是這個也可以獲取Constructor<Student> constructor = s1.getDeclaredConstructor(); //無參構造器是private的,所以需要暴力反射constructor.setAccessible(true); Student stu = constructor.newInstance();System.out.println(stu);}
--------------輸出---------------
無參構造器執行...
Student{age=0, name='null'}
三、加載類的成員變量
加載成員變量對象的步驟:
- 獲取類的Class對象
- 調用方法獲得成員變量對象
- 使用:調用成員變量對象的get()/set()方法
獲取構成員變量的方法如下
方法 | 說明 |
---|---|
public Field[] getFields() | 獲取類的全部成員變量(只能獲取public修飾的) |
public Field[] getDeclaredFields() | 獲取類的全部成員變量(任意修飾都可以拿到) |
public Field getField(String name) | 獲取類的某個成員變量(只能獲取public修飾的) |
public Field getDeclaredField(String name) | 獲取類的某個成員變量(任意修飾都可以拿到) |
方法 | 說明 |
---|---|
void set(Object obj, Object value); | 賦值 |
Object get(Object obj) | 取值 |
public void setAccessible(boolean flag) | 設置為true,表示禁止檢查訪問控制(暴力反射) |
@Testpublic void testAllField() throws Exception {Class<Student> student = Student.class;//單個時輸入變量名Field age = student.getDeclaredField("age");Student student1 = new Student();age.setAccessible(true);age.set(student1,18);System.out.println(student1);}
------------輸出--------------
無參構造器執行...
Student{age=18, name='null'}
四、加載類的成員方法
加載成員方法對象的步驟:
- 獲取類的Class對象
- 調用方法獲得成員方法對象
- 使用:調用成員方法對象的invoke()方法
方法 | ||
---|---|---|
Method[] getMethods() | 獲取類的全部成員變量(只能獲取public修飾的) | |
Method[] getDeclaredMethods() | 獲取類的全部成員變量(任意修飾都可以拿到) | |
Method getMethod(String name, Class<?>… parameterTypes) | 獲取類的某個成員變量(只能獲取public修飾的) | |
Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 獲取類的某個成員變量(任意修飾都可以拿到) |
Mehode提供的方法 | 說明 |
---|---|
public Object invoke(Object obj, Object… args) | 觸發某個對象的該方法執行 |
public void setAccessible(boolean flag) | 設置為true,表示禁止檢查訪問控制(暴力反射) |
@Testpublic void testAllMethod() throws Exception {Class<Animal> animal = Animal.class;//參數為方法的名稱Method declaredMethod = animal.getDeclaredMethod("eat");declaredMethod.setAccessible(true);Animal animal1 = new Animal();Object invoke = declaredMethod.invoke(animal1);//返回值為nullSystem.out.println(invoke);}
-----------輸出--------------
動物吃
null
完結~