如何使用java反射在运行时调用每个方法都有不同参数的类的方法?

如何使用java反射在运行时调用每个方法都有不同参数的类的方法?,java,reflection,Java,Reflection,我正在为selenium开发一个关键字驱动的框架。 我在一个单独的类中编写了我的方法。 下面的类包含打开主页、输入用户名和密码以及单击登录按钮的操作方法 package actions; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class adminlogin { WebDriver driver; public adminlogin(WebDriv

我正在为selenium开发一个关键字驱动的框架。 我在一个单独的类中编写了我的方法。 下面的类包含打开主页、输入用户名和密码以及单击登录按钮的操作方法

package actions;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class adminlogin {
    WebDriver driver;
    public adminlogin(WebDriver driver){
        this.driver = driver;
    }
    public void adminopenhomepage() {
        driver.get("http://localhost/carrental/admin/");
    }
    public void adminenterusername(WebElement username) {
        username.sendKeys("admin");
    }
    public void adminenterpassword(WebElement password) {
        password.sendKeys("Test@12345");
    }
    public void adminclickloginbutton(WebElement loginbutton) {
        loginbutton.click();
    }
    public void adminclosebrowser() {
        driver.close();
    }
}
我在一个列表中有这些关键字,我迭代这些关键字,并使用反射调用上述方法。 我想做的一种方法是在运行时获取参数类型和参数数量,以便可以相应地传递参数。我试图使用getDeclaredMethod(关键字)获取该方法,但这仅适用于那些没有参数的方法,如adminopenhomepage(),并且对所有其他方法都不提供例外,因为它们接受参数。有人能告诉我怎么解决这个问题吗

for(String str : originalkeywords) {
    String keyword = str;
    String actioncl = keywordvsac.get(keyword);
    String objectcl = keywordvsor.get(keyword);

    Class<?> cls = Class.forName("actions."+actioncl);
    Method methodcall = cls.getDeclaredMethod(keyword);

    Parameter[] parameters = methodcall.getParameters();        
    System.out.println(Arrays.toString(parameters));
}
for(字符串str:originalkeywords){
字符串关键字=str;
字符串actioncl=keywordvsac.get(关键字);
String objectcl=keywordvsor.get(关键字);
Class cls=Class.forName(“actions.”+actioncl);
方法methodcall=cls.getDeclaredMethod(关键字);
参数[]参数=methodcall.getParameters();
System.out.println(Arrays.toString(parameters));
}

谢谢。

要通过反射调用方法,需要三件事:

  • 对象的类名
  • 为其调用方法的类实例
  • 方法参数
  • 直接从中获取一个示例,要调用方法,只需编写:

        Class<?> c = Class.forName(args[0]);
        Class[] argTypes = new Class[] { String[].class };
        Method main = c.getDeclaredMethod("main", argTypes);
        String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
        System.out.format("invoking %s.main()%n", c.getName());
        main.invoke(null, (Object)mainArgs);
    
    Class c=Class.forName(args[0]);
    类[]argTypes=新类[]{String[].Class};
    方法main=c.getDeclaredMethod(“main”,argTypes);
    字符串[]mainArgs=Arrays.copyOfRange(args,1,args.length);
    System.out.format(“调用%s.main()%n”,c.getName());
    调用(null,(Object)mainArgs);
    
    要显示参数名,只需参考java官方文档中的相关内容


    我希望它能有所帮助。

    您可以使用
    AdminLogin.class.getDeclaredMethods()
    和使用for循环将所有方法映射到某些操作,这样您就可以使用
    方法.getParameters()
    读取参数,但请注意,参数可能没有名称-这必须在编译器中使用
    -parameters
    标志启用

    概念证明:

    Map<String, Callable> mappedMethods = new HashMap<>(); // you can use runnable etc, I used callable as I don't want to catch exceptions in this example code - you should.
    AdminLogin instance = new AdminLogin();
    WebElement usernameElement = null; // idk how you get instance of this
    WebElement passwordElement = null; // idk how you get instance of this
    for (Method method : AdminLogin.class.getDeclaredMethods()) {
       Parameter[] parameters = method.getParameters();
       Object[] args = new Object[parameters.length];
       for (int i = 0; i < parameters.length; i++) {
           Parameter parameter = parameters[i];
           if ((parameter.getType() == WebElement.class) && parameter.getName().equals("username")) {
               args[i] = usernameElement;
           }
           else if ((parameter.getType() == WebElement.class) && parameter.getName().equals("password")) {
               args[i] = passwordElement;
           } else {
               // log some info/throw exception, whatever you need for methods that can't be mapped
               break;
           }
       }
       mappedMethods.put(method.getName(), () -> method.invoke(instance, args));
    }
    
    Map-mappedMethods=new HashMap();//您可以使用runnable等,我使用callable,因为我不想在这个示例代码中捕获异常-您应该这样做。
    AdminLogin实例=新建AdminLogin();
    WebElement usernameElement=null;//idk你是如何得到这个实例的
    WebElement passwordElement=null;//idk你是如何得到这个实例的
    对于(方法:AdminLogin.class.getDeclaredMethods()){
    Parameter[]parameters=method.getParameters();
    Object[]args=新对象[parameters.length];
    对于(int i=0;imethod.invoke(instance,args));
    }
    
    现在,您可以从map中按名称调用这些callables

    但是请注意,您应该在这里添加更多的抽象,例如,如果您有更多的参数类型需要处理,那么在每个类中复制这些代码将是一个坏主意。
    还可以阅读java中的注释,它们对于标记这样的特殊方法和参数很有用,但不要过度使用它们


    还要注意的是,
    getDeclaredMethods
    返回的方法没有特定的顺序,当然也没有按照类中声明的顺序返回

    无关:阅读Java命名约定。类名是大写的。您已经将类命名为Admin。。。那么,为什么在所有的方法名称中不断重复这个字符串呢?顺便说一句,方法名是固定的。好的,我将按照惯例更改类名。不确定您对方法名称的看法。方法名称根据执行操作的角色给出。如果是用户,我会将他们命名为useropenhomepage等。不知道你在说什么。对于我要问的问题,您有什么解决方案吗?您显示的代码不调用异常?我认为您应该阅读并相应地增强您的问题。您可以通过使用
    c.getDeclaredMethod(“main”,String[].class)简化此代码。然后,首先用type
    Object
    声明
    mainArgs
    ,使随后的类型转换过时。