@
目錄
- 1 擷取 Method
- 1.1 方法
- 1.2 執行個體
- 2 Method 的方法
- 2.1 Java 方法基礎知識
- 2.2 修飾符相關方法
- 2.2.1 擷取修飾符
- 2.2.2 判斷是否為 default 方法
- 2.2.3 判斷是否為 bridge 方法
- 2.2.4 判斷是否為 synthetic 方法
- 2.3 擷取傳回值類型
- 2.4 擷取方法名
- 2.5 擷取傳回值
- 2.5.1 方法
- 2.5.2 測試
- 2.6 參數
- 2.7 異常
- 2.7.1 方法
- 2.7.2 測試
- 2.8 注解
- 2.9 調用相關
- 2.9.1 通路權限控制
- 2.9.2 方法調用
- 2.9.3 測試
Method
類描述的是類對象的方法資訊。 其中包含了被反射方法的資訊, 通路資訊。在運作時, 我們可以通過該類進行方法的調用。
因為 Java 中的
java.lang.reflect
包下所有類的構造函數都不為 public, 同時類都是 final 類型的, 是以, 不能直接通過外部 new 來擷取該方法。
擷取所有的 public 方法,包括其父類, 接口的
public Method[] getMethods();
擷取指定參數的 public 方法, 包括其父類, 接口的
public Method getMethod(String name, Class<?>... parameterTypes);
擷取聲明(public, private, protected, friendly)的所有普通方法
public Method[] getDeclaredMethods();
擷取聲明(public, private, protected, friendly)的指定參數的普通方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes);
該執行個體稱為執行個體1。
定義父類
public class ParentClass {
private String privateMethod(){
return "ParentClass::privateMethod";
}
String defaultMethod(){
return "ParentClass::defaultMethod";
}
protected String protectedMethod(){
return "ParentClass::protectedMethod";
}
public String publicMethod(){
return "ParentClass::public";
}
}
定義子類
public class ChildClass extends ParentClass {
private String childPrivateMethod(){
return "ChildClass::childPrivateMethod";
}
String childDefaultMethod(){
return "ChildClass::childDefaultMethod";
}
protected String childProtectedMethod(){
return "ChildClass::childProtectedMethod";
}
public String childPublicMethod(){
return "ChildClass::childPublicMethod";
}
測試類
public class MethodTest {
public static void main(String[] args) {
Class<ChildClass> childClass = ChildClass.class;
Method[] methods = childClass.getMethods();
System.out.println("============getMethods================");
for (Method method:methods) {
System.out.println(method.getName());
}
Method[] dMethods = childClass.getDeclaredMethods();
System.out.println("============getMethods================");
for (Method method:dMethods) {
System.out.println(method.getName());
}
}
}
輸出

Method
是存儲方法相關的資訊, 是以, 其方法及屬性都跟這些相關。
下面是一個方法的屬性:
- 修飾符:修飾符,這是可選的,告訴編譯器如何調用該方法。定義了該方法的通路類型。
- 傳回值 :方法可能會傳回值。returnValueType 是方法傳回值的資料類型。有些方法執行所需的操作,但沒有傳回值。在這種情況下,returnValueType 是關鍵字void。
- 方法名:是方法的實際名稱。方法名和參數表共同構成方法簽名。
- 參數:參數像是一個占位符。當方法被調用時,傳遞值給參數。這個值被稱為實參或變量。參數清單是指方法的參數類型、順序和參數的個數。參數是可選的,方法可以不包含任何參數。
- 異常:方法中抛出的異常類型。
- 注解:方法上的注解。
在 Java 中, 修飾符以數字的形式存在, 通過 int 存儲了32位的數字, 就可以存儲多個數值, 此種存儲方式在
Modifier
中會進行講解。
public int getModifiers() {
return modifiers;
}
同樣以之前 [執行個體1] 的代碼進行測試, 重寫寫一個測試方法
public static void main(String[] args) {
Class<ChildClass> childClass = ChildClass.class;
Method[] methods = childClass.getMethods();
System.out.println("============getMethods================");
for (Method method:methods) {
System.out.println(method.getName()+"::"+Modifier.toString(method.getModifiers()));
}
}
結果
public boolean isDefault() {
// Default methods are public non-abstract instance methods
// declared in an interface.
return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
Modifier.PUBLIC) && getDeclaringClass().isInterface();
}
這是 Java 8 中引入的概念:預設方法是在接口中聲明的, public, 非 abstract 的實體方法(實體方法即不是 static 方法)。
在此處不展開。
public boolean isBridge() {
return (getModifiers() & Modifier.BRIDGE) != 0;
}
判斷是否為橋接方法。
public boolean isSynthetic() {
return super.isSynthetic();
}
判斷是否為 synthetic 方法。
public Class<?> getReturnType() {
return returnType;
}
public String getName() {
return name;
}
擷取傳回值的類型有兩種:
擷取到傳回值的
Class
類型的對象
public Class<?> getReturnType() {
return returnType;
}
Type
public Type getGenericReturnType() {
if (getGenericSignature() != null) {
return getGenericInfo().getReturnType();
} else { return getReturnType();}
}
定義類
public class Animal {
private Map<String,Animal> friends = new HashMap<>();
public void addFriend(String name, Animal animal){
friends.put(name,animal);
}
public Animal callFriend(String name){
return friends.get(name);
}
public<T extends Animal> T callFriend(String name, T unusedTypeObj){
return (T)friends.get(name);
}
public static void main(String[] args) {
Class<Animal> clazz = Animal.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method:methods) {
System.out.println(method.getName()+"::"+method.getReturnType()+"::"+method.getGenericReturnType());
}
}
}
擷取所有的參數, 傳回值是
Class
數組
public Class<?>[] getParameterTypes()
擷取所有參數, 傳回值是
Type
public Type[] getGenericParameterTypes()
擷取參數的所有注解
public Annotation[][] getParameterAnnotations()
擷取所有的異常, 傳回值是
Class
public Class<?>[] getExceptionTypes()
Type
public Type[] getGenericExceptionTypes()
擷取注解異常
public AnnotatedType[] getAnnotatedExceptionTypes()
public class ExceptionExample {
public static void main(String[] args) throws Exception {
Method m = ExceptionExample.class.getMethod("method");
System.out.println(m.getGenericExceptionTypes()[0]);
System.out.println(m.getExceptionTypes()[0]);
}
public static <T extends Throwable> void method() throws T {}
}
擷取聲明的所有注解
public Annotation[] getDeclaredAnnotations()
抑制Java的權限控制檢查:在針對非public時方法時, 可以考慮這麼用
public void setAccessible(boolean flag)
方法調用
public Object invoke(Object obj, Object... args)
使用示例1中的代碼
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Class<ChildClass> childClass = ChildClass.class;
Method[] methods = childClass.getDeclaredMethods();
System.out.println("============getMethods================");
ChildClass child = new ChildClass();
for (Method method:methods) {
method.setAccessible(true);
System.out.println(method.invoke(child));
}
如果注釋權限控制, 輸出如下
取消注釋之後
作者:阿進的寫字台
出處:https://www.cnblogs.com/homejim/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。