Class 類 getMethod、getMethods、getDeclaredMethod、getDeclaredMethods四者區別
在學習 Java反射 的過程中,注意到Class類 有 以下四個方法:
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
public Method[] getMethods() throws SecurityException
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
public Method[] getDeclaredMethods() throws SecurityException
通過查閱資料學習了各個方法的作用、及相互之間的區別,在此進行整理記錄,如有錯誤之處,還請指正。
getMethod
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
返回一個 Method 物件,它反映當前 Class 物件所表示的類或介面中指定name的公共(public)成員方法(包括父類繼承的、介面實現的、父介面繼承的)。
name 引數用於指定所反映的方法的名稱。parameterTypes 引數是按宣告順序標識該方法形參型別的 Class 物件的一個數組。如果 parameterTypes 為 null,則按空陣列處理。
BUT:如果 name 是 “< init >;” 或 “< clinit >”,則將引發 NoSuchMethodException。(< init >和< clinit >的區別)
要反映的方法由下面的演算法匹配確定(設 C 為當前Class物件所表示的類):
1. 在 C 中搜索任一匹配的方法。如果找不到匹配的方法,則將在 C 的超類上遞迴呼叫第 1 步演算法。
2. 如果在第 1 步中沒有找到任何方法,則在 C 的超介面中搜索匹配的方法。如果找到了這樣的方法,則反映該方法。
在C 中查詢匹配方法的規則:如果 C 正好聲明瞭一個具有指定名稱的公共方法並且恰恰有相同的形參型別,則它就是反映的方法。如果在 C 中找到了多個這樣的方法,並且其中有一個方法的返回型別比其他方法的返回型別都特殊,則反映該方法;否則將從中任選一個方法。
注意:類中可能有多個匹配方法,因為儘管 Java 語言禁止類宣告帶有相同方法簽名(方法名+引數列表)但不同返回型別的多個方法,但 Java 虛擬機器並不禁止。這增加了虛擬機器的靈活性,可以用來實現各種語言特性。例如,可以使用橋方法 (brige method)實現協變返回;橋方法以及將被重寫的方法將具有相同的簽名,不同的返回型別。
如果當前Class物件 代表著陣列型別,那麼getMethod方法不會查詢clone()方法。
getMethod可以獲取當前Class 物件所代表的類中的 靜態方法(包括從超類繼承的靜態方法)
Java8新增:
Static methods declared in superinterfaces of the class or interface represented by this Class object are not considered members of the class or interface.
getMethods
public Method[] getMethods() throws SecurityException
返回一個Method物件的陣列,這些Method物件反映當前 Class 物件所表示的類或介面的公共 member 方法。(包括那些由該類或介面宣告的以及從超類和超介面繼承的方法)
如果當前Class物件代表陣列型別,則getMethods 返回從 Object 類繼承的所有(公共)member 方法的Method物件。但不包括clone()方法的Method物件。
如果此 Class 物件表示一個沒有公共成員方法的類或介面(包括從超類、超介面 繼承實現的方法),則此方法返回長度為 0 的Method陣列。(但一個類永遠都會有公有方法,從Object繼承的)
如果當前Class 物件表示一個基本型別或 void,則此方法返回長度為 0 的Method陣列。
類初始化方法 < clinit > 不包含在返回的Method陣列中
當前Class物件所代表的類中 的靜態方法(包括從父類繼承的靜態方法)也會被包含在返回的Method陣列中
If this Class object represents a type that has multiple public methods with the same name and parameter types, but different return types, then the returned array has a Method object for each such method.
Static methods declared in superinterfaces of the class or interface represented by this Class object are not considered members of the class or interface.
返回的Method陣列中的元素沒有排序,也沒有任何特定的順序。
getDeclaredMethod
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
返回一個 Method 物件,該物件反映當前 Class 物件所表示的類或介面中name指定的已宣告方法(包括private修飾的方法。該方法必須在當前類或介面中有宣告,如 抽象方法的實現。如果當前類中 某一方法繼承自父類,但該類中並未對其重寫(也就是說,該類中不存在這個方法的宣告),則呼叫getDeclaredMethod將會丟擲NoSuchMethodException)。
引數:
name 指定方法名
parameterTypes 是 Class 物件的一個數組,它按宣告順序標識該方法的形參型別。
如果在某個類中聲明瞭帶有相同引數型別的多個方法,並且其中有一個方法的返回型別比其他方法的返回型別都特殊,則返回該方法;否則將從中任選一個方法。
如果name是 “< init >” 或 “< clinit >”,則引發一個 NoSuchMethodException。
getDeclaredMethods
返回一個 Method 物件陣列,這些Method物件反映當前 Class 物件表示的類或介面宣告的所有方法,包括public、protected、預設 和 private 方法,但不包括未宣告的方法(如 繼承 但未重寫的方法 )。
If this Class object represents a type that has multiple declared methods with the same name and parameter types, but different return types, then the returned array has a Method object for each such method.
類初始化方法 < clinit > 不包含在返回的Method陣列中。
如果該類或介面未宣告任何方法,或者此 Class 物件 表示一個基本型別、一個數組型別 或 void,則此方法返回一個長度為 0 的Method陣列。
返回Method陣列中的元素沒有排序,也沒有任何特定的順序。
簡單總結:
- getMethod : 能獲取當前Class物件表示的類中 一個指定 方法名的 公有方法 的Method物件 (包括繼承的)。
- getMethods : 能獲取當前Class物件表示的類中 所有的 公有方法 的Method 物件 (包括繼承的)。
- getDeclaredMethod : 能獲取當前Class物件表示的類中 一個指定 方法名的,並且在該類中存在宣告的方法 的Method物件。(無視訪問修飾符)
- getDeclaredMethods : 能獲取當前Class物件表示的類中 所有存在宣告的方法 的Method物件。(無視訪問修飾符)
- 但要注意 陣列、基本型別、void、< init >、< clinit > 幾個特例。