我在使用appium java客户端时遇到了麻烦,因为似乎他们在项目中做得很奇怪。
基本上,他们在他们的项目中使用硒,这应该可以正常工作,但是他们将硒中的一个软件包部分复制到了他们的项目中( org.openqa.selenium ),并对其中的类做了一些小改动。基本上,他们向接口添加了泛型。现在,我们在不同库中的同一包中有重复的类,这当然会导致问题。
我创建了一个简单的gradle项目来演示这一点。 遵循我的 build.gradle :
plugins {
id 'java-library'
}
dependencies {
api 'io.appium:java-client:6.1.0'
}
repositories {
jcenter()
}
我的课程 Interactions.java :
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class Interactions {
public static void touchWebElement(By by, WebDriver driver) {
touchWebElement(driver.findElement(by), driver);
}
public static void touchWebElement(WebElement element, WebDriver driver) {
// TO SOMETHING
}
}
现在,如果我编译该项目,则会出现以下错误:
The method touchWebElement(By, WebDriver) is ambiguous for the type Interactions Interactions.java line 8
我认为这是模棱两可的,因为接口 WebElement 存在两次。
如何解决该问题?
我愿意接受所有解决问题的想法。预先谢谢你!
答案 0 :(得分:3)
问题不是重复的类,而是泛型的使用方式。以下是一些MCVE来复制Appium WebDriver
类中的情况:
package de.scrum_master.stackoverflow;
public interface WebElement {}
package de.scrum_master.stackoverflow;
public interface WebDriver {
<T extends WebElement> T findElement();
}
package de.scrum_master.stackoverflow;
public class Application {
static WebDriver webDriver;
static void myOverloadedMethod(String text) {}
static void myOverloadedMethod(WebElement text) {}
public static void main(String[] args) {
// These 3 variants work
myOverloadedMethod("test");
myOverloadedMethod((WebElement) webDriver.findElement());
WebElement webElement = webDriver.findElement();
myOverloadedMethod(webElement);
// This one does not work
myOverloadedMethod(webDriver.findElement());
}
}
说明:由于type erasure doSomething
的通用返回类型<T extends WebElement>
的计算结果为Object
,因此在尝试将该结果用于调用myOverloadedMethod(..)
时,编译器不知道选择哪种方法。
解决方案:您需要通过强制转换或显式声明包含方法参数的变量的类型来提供帮助。
PS::如果将接口定义从interface WebDriver
修改为interface WebDriver<T>
,则编译错误将消失。但是Appium的实现并没有做到这一点,可能是因为他们想要与原始Selenium类保持尽可能兼容(?)。你必须问他们。
更新:由于OP似乎在理解我的答案时遇到问题,或者认为我没有尝试过他的示例代码,所以我当然会重用并理解他的问题:
package de.scrum_master.appium;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class Interactions {
public static void touchWebElement(WebElement element, WebDriver driver) {}
public static void touchWebElement(By by, WebDriver driver) {
// Works
WebElement webElement = driver.findElement(by);
touchWebElement(webElement, driver);
// Works
touchWebElement((WebElement) driver.findElement(by), driver);
// Ambiguous due to type erasure -> does not work
touchWebElement(driver.findElement(by), driver);
}
}
这里绝对不需要重命名方法,重新打包任何类或执行其他类型的Maven / Gradle特技。