簡體   English   中英

如何使用Java反射在運行時調用每個方法具有不同參數的類的方法?

[英]How to invoke methods of a class where each method has different arguments at run time using java reflections?

我正在研究硒的關鍵字驅動框架。 我在單獨的類中編寫了方法。 以下是包含用於打開主頁,輸入用戶名和密碼並單擊登錄按鈕的操作方法的類。

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

謝謝。

要通過反射調用方法,您需要三件事:

  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官方文檔的另一頁即可

希望對您有所幫助。

您可以使用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返回的方法沒有特定的順序,並且肯定不按與類中聲明的順序相同的順序返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM