[英]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));
}
謝謝。
要通過反射調用方法,您需要三件事:
直接從官方文檔中獲取示例,調用方法只需編寫:
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.