📜  如何使用反射动态地在Java中按名称调用方法?

📅  最后修改于: 2022-05-13 01:55:02.428000             🧑  作者: Mango

如何使用反射动态地在Java中按名称调用方法?

Java反射 API 为我们提供了有关对象所属的类的信息,包括该类中的方法。使用这些反射 API,我们将能够使用其名称为类中的方法调用指针。

有两个函数用于此目的:

  1. 使用其名称调用方法
  2. 在类中按名称查找方法并调用相同的方法

1.用名字调用方法

getDeclaredMethod() 用于此目的

语法

Class.getDeclaredMethod(“method name”, parameterType)

方法名称:我们要按名称查找的方法

Parameter Type : 方法接受的参数类型

返回类型:此方法将返回一个引用方法地址的对象,然后该对象将用于调用该方法。我们将为此使用 invoke 方法

如果有很多重载的方法同名,编译器会调用匹配参数的方法

调用函数

将用于调用使用 Method 对象的方法

语法

Method.invoke(classObj, param1, param2…)

methodObj:从 getDeclaredMethod 返回的方法对象

参数:用于调用方法的参数值。如果该方法没有任何要传递的参数,那么我们将在这里传递null

例子

Java
// Java program to invoke method with its name
// using Rfelection API
  
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
  
class GFG {
    public void printMessage(String message)
    {
        System.out.println(
            "you invoked me with the message:" + message);
    }
    
    public static void main(String[] args) throws Exception
    {
        System.out.println("Invoke method by Name in Java using Reflection!");
        
        // create class object to get its details
        GFG obj = new GFG();
        
        Class classObj = obj.getClass();
  
        // get method object for "printMessage" function by
        // name
        Method printMessage = classObj.getDeclaredMethod("printMessage", String.class);
  
        try {
            
            // invoke the function using this class obj
            // pass in the class object
            printMessage.invoke(obj, "hello"); 
        }
        
        catch (InvocationTargetException e) 
        {
            System.out.println(e.getCause());
        }
    }
}


Java
// Java program of Finding a method by Name in a class
// and invoking the same
  
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
  
class GeeksForGeeks {
    public void printMessage(String message)
    {
        System.out.println(
            "you invoked me with the message:" + message);
    }
  
    public void addMe(int num1, int num2)
    {
        System.out.println("sum is:" + (num1 + num2));
    }
  
    public static void main(String[] args) throws Exception
    {
        System.out.println("Find method by Name in Java using Reflection!");
        
        // create class object to get its details
        GeeksForGeeks obj = new GeeksForGeeks();
        
        Class classObj = obj.getClass();
  
        // get all methods in the class
        Method[] allMethods = classObj.getDeclaredMethods();
  
        // loop through the methods to find the method addMe
        for (Method m : allMethods) {
            
            String methodName = m.getName();
            if (methodName.equals("addMe")) {
                try {
                    
                    // invoke the method directly with its
                    // parameters
                    m.invoke(obj, 10, 20);
                }
                catch (InvocationTargetException e) {
                }
            }
        }
    }
}


输出
Invoke method by Name in Java using Reflection!
you invoked me with the message:hello

2.在类中按名称查找方法并调用该方法

如果我们不知道确切的方法参数,我们也可以获取类中的所有方法并通过名称搜索方法,然后获取它的详细信息

  • 我们将使用getDeclaredMethods () API 进行相同的操作。这将返回类中的 Method 对象数组
  • 我们可以使用它来循环遍历 Method 对象,并使用getName() 按名称查找方法。
  • 然后我们将使用 getGenericParameterTypes()找到它需要的参数并getGenericReturnType()找到它的返回类型
  • 一旦我们有了参数和返回类型,我们将使用上面提到的 invoke函数来调用方法

语法

Method[] methods = Class.getDeclaredMethods()  

示例

Java

// Java program of Finding a method by Name in a class
// and invoking the same
  
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
  
class GeeksForGeeks {
    public void printMessage(String message)
    {
        System.out.println(
            "you invoked me with the message:" + message);
    }
  
    public void addMe(int num1, int num2)
    {
        System.out.println("sum is:" + (num1 + num2));
    }
  
    public static void main(String[] args) throws Exception
    {
        System.out.println("Find method by Name in Java using Reflection!");
        
        // create class object to get its details
        GeeksForGeeks obj = new GeeksForGeeks();
        
        Class classObj = obj.getClass();
  
        // get all methods in the class
        Method[] allMethods = classObj.getDeclaredMethods();
  
        // loop through the methods to find the method addMe
        for (Method m : allMethods) {
            
            String methodName = m.getName();
            if (methodName.equals("addMe")) {
                try {
                    
                    // invoke the method directly with its
                    // parameters
                    m.invoke(obj, 10, 20);
                }
                catch (InvocationTargetException e) {
                }
            }
        }
    }
}
输出
Find method by Name in Java using Reflection!
sum is:30

invoke 方法抛出的异常

当被调用的底层方法抛出异常时,Invoke 方法将抛出InvocationTargetException 。我们将能够通过使用 InvocationTargetException 的 getCause() 方法来检索方法的异常