Java核心技术笔记——第 12 章 反射
轉載自:[https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html]
12 反射
1. 引入反射
通常情況下,調用一個類的方法的步驟如下:
通過這種方式調用方法時,必須要知道類的定義以及類的所有屬性和方法。代碼如下:
Apple apple = new Apple(); //直接初始化,「正射」 apple.setPrice(4);另一種調用類方法的方式是:反射。示例如下:
//獲取類的class對象 Class clz = Class.forName("com.chenshuyi.reflect.Apple"); //獲取類的指定方法的method對象 Method method = clz.getMethod("setPrice", int.class); //獲取類的默認構造器 Constructor constructor = clz.getConstructor(); //創建類的對象 Object object = constructor.newInstance(); //調用方法 method.invoke(object, 4);上面兩段代碼的執行結果,其實是完全一樣的。但是其思路完全不一樣,第一段代碼在未運行時就已經確定了要運行的類(Apple),而第二段代碼則是在運行時通過字符串值才得知要運行的類(com.chenshuyi.reflect.Apple)。
2. 反射定義
反射就是在運行時才知道要操作的類是什么,并且可以在運行時獲取類的完整構造,并調用對應的方法。
3. 示例的完整代碼
public class Apple {private int price;public int getPrice(){return price;}public void setPrice(int price) {this.price = price;}public static void main(String[] args) throws Exception{//正常的調用Apple apple = new Apple();apple.setPrice(5);System.out.println("Apple Price:" + apple.getPrice());//使用反射調用Class clz = Class.forName("com.chenshuyi.api.Apple");Method setPriceMethod = clz.getMethod("setPrice", int.class);Constructor appleConstructor = clz.getConstructor();Object appleObj = appleConstructor.newInstance();setPriceMethod.invoke(appleObj, 14);Method getPriceMethod = clz.getMethod("getPrice");System.out.println("Apple Price:" + getPriceMethod.invoke(appleObj));} }4. 反射調用的步驟
一般情況下我們使用反射獲取一個對象的步驟:
獲取類的 Class 對象實例
Class clz = Class.forName("com.zhenai.api.Apple");根據 Class 對象實例獲取 Constructor 對象
Constructor appleConstructor = clz.getConstructor();使用 Constructor 對象的 newInstance 方法獲取反射類對象
Object appleObj = appleConstructor.newInstance();如果要調用某一個方法,則需要經過下面的步驟:
獲取方法的 Method 對象
Method setPriceMethod = clz.getMethod("setPrice", int.class);利用 invoke 方法調用方法
setPriceMethod.invoke(appleObj, 14);5. 反射常用的 API
1. 獲取反射中的 Class 對象
在反射中,要獲取一個類或調用一個類的方法,我們首先需要獲取到該類的 Class 對象。在 Java API 中,獲取 Class 類對象有三種方法:
使用 Class.forName 靜態方法。當你知道類的全路徑名時,你可以使用該方法獲取 Class 類對象。
Class clz = Class.forName("java.lang.String");使用 類型名.class 。
Class clz = String.class;使用類對象的 getClass() 方法。
String str = new String("Hello"); Class clz = str.getClass();
2. 通過反射創建類對象
通過反射創建類對象主要有兩種方式(newInstance() 的返回值是 Object):
通過 Class 對象的 newInstance() 方法
Class clz = Apple.class; Apple apple = (Apple)clz.newInstance();通過 Constructor 對象的 newInstance() 方法。
Class clz = Apple.class; Constructor constructor = clz.getConstructor(); Apple apple = (Apple)constructor.newInstance();
通過 Constructor 對象創建類對象可以選擇特定構造方法,而通過 Class 對象則只能使用默認的無參數構造方法。下面的代碼就調用了一個有參數的構造方法進行了類對象的初始化:
Class clz = Apple.class; Constructor constructor = clz.getConstructor(String.class, int.class); Apple apple = (Apple)constructor.newInstance("紅富士", 15);3. 通過反射獲取類屬性、方法、構造器
獲取類的屬性
- Field getField(String name):獲取 Class 對象對應類的指定公有屬性。
- Field[] getFields():獲取 Class 對象對應類的所有公有屬性(包括從父類中繼承的公有屬性),無法獲取類的私有屬性。
- Field[] getDeclaredFields():獲取 Class 對象對應類的所有屬性(僅限本類中定義的公有、默認、保護、私有屬性,不包括從父類中繼承的屬性)。
- Field getDeclaredField(String name):獲取 Class 對象對應類的指定屬性(僅限本類中定義的公有或默認或保護或私有屬性,不包括從父類中繼承的屬性)。
獲取類的方法
- Method getMethod(String name, Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有方法。
- Method[] getMethods(): 獲取 Class 對象對應類的所有公有方法(包括從父類中繼承的公有方法),無法獲取類的私有方法。
- Method[] getDeclaredMethods():獲取 Class 對象對應類的所有方法(僅限本類中定義的公有、默認、保護、私有方法,不包括從父類中繼承的方法,以及本類的構造器)。
- Method getDeclaredMethod(String name, Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有方法(僅限本類中定義的公有或默認或保護或私有方法,不包括從父類中繼承的方法)。
獲取類的構造器
- Constructor<T> getConstructor(Class<?>... parameterTypes):獲取 Class 對象對應類的指定公有構造器。
- Constructor<?>[] getConstructors():獲取 Class 對象對應類的所有公有構造器。
- Constructor<?>[] getDeclaredConstructors():獲取 Class 對象對應類的所有構造器。
- Constructor<?>[] getDeclaredConstructor(Class<?>... parameterTypes):獲取 Class 對象對應類的指定構造器(公有或私有)。
轉載于:https://www.cnblogs.com/echie/p/9785676.html
總結
以上是生活随笔為你收集整理的Java核心技术笔记——第 12 章 反射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PCB SI9000阻抗计算引擎Web方
- 下一篇: 网络(图)(数学)