为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

汪汪一只猫 2021-11-17 15:25:25
我正在为 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(keyword) 获取该方法,但这仅适用于那些没有像 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));}
查看完整描述

2 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

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

  1. 对象的类名

  2. 为其调用方法的类实例

  3. 方法参数。

直接从官方文档中拿一个例子,调用一个方法只需写:

   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);

要显示参数名称,只需查阅java官方文档的另一页,讨论它。


我希望它有帮助。


查看完整回答
反对 回复 2021-11-17
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

您可以使用AdminLogin.class.getDeclaredMethods()for 循环将所有方法映射到某些操作,然后您可以使用读取参数,method.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));

}

现在您可以从地图中按名称调用可调用对象。


但是请注意,您应该在此处添加更多抽象,因为如果您有更多参数类型来处理或为每个类复制此代码,则 ifs 之墙将是一个坏主意。

另请阅读 Java 中的注解,它们对于标记这样的特殊方法和参数很有用,但不要过度使用它们。


另请注意,getDeclaredMethods返回方法没有特定的顺序,并且肯定与类中声明的顺序不同。


查看完整回答
反对 回复 2021-11-17
  • 2 回答
  • 0 关注
  • 252 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信