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

我正在为 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));

}


汪汪一只猫
浏览 253回答 2
2回答

慕的地6264312

要通过反射调用方法,您需要三件事:对象的类名为其调用方法的类实例方法参数。直接从官方文档中拿一个例子,调用一个方法只需写:&nbsp; &nbsp;Class<?> c = Class.forName(args[0]);&nbsp; &nbsp; Class[] argTypes = new Class[] { String[].class };&nbsp; &nbsp; Method main = c.getDeclaredMethod("main", argTypes);&nbsp; &nbsp; String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);&nbsp; &nbsp; System.out.format("invoking %s.main()%n", c.getName());&nbsp; &nbsp; main.invoke(null, (Object)mainArgs);要显示参数名称,只需查阅java官方文档的另一页,讨论它。我希望它有帮助。

慕尼黑的夜晚无繁华

您可以使用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 thisWebElement passwordElement = null; // idk how you get instance of thisfor (Method method : AdminLogin.class.getDeclaredMethods()) {&nbsp; &nbsp;Parameter[] parameters = method.getParameters();&nbsp; &nbsp;Object[] args = new Object[parameters.length];&nbsp; &nbsp;for (int i = 0; i < parameters.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp;Parameter parameter = parameters[i];&nbsp; &nbsp; &nbsp; &nbsp;if ((parameter.getType() == WebElement.class) && parameter.getName().equals("username")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;args[i] = usernameElement;&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp;else if ((parameter.getType() == WebElement.class) && parameter.getName().equals("password")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;args[i] = passwordElement;&nbsp; &nbsp; &nbsp; &nbsp;} else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// log some info/throw exception, whatever you need for methods that can't be mapped&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp;}&nbsp; &nbsp;mappedMethods.put(method.getName(), () -> method.invoke(instance, args));}现在您可以从地图中按名称调用可调用对象。但是请注意,您应该在此处添加更多抽象,因为如果您有更多参数类型来处理或为每个类复制此代码,则 ifs 之墙将是一个坏主意。另请阅读 Java 中的注解,它们对于标记这样的特殊方法和参数很有用,但不要过度使用它们。另请注意,getDeclaredMethods返回方法没有特定的顺序,并且肯定与类中声明的顺序不同。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java