绑定不匹配错误和javagenerics方法

我收到以下错误:

Bound mismatch: The generic method constructPage(WebDriver, int, Class) of type Page is not applicable for the arguments (WebDriver, int, Class). The inferred type HomePage is not a valid substitute for the bounded parameter <T extends Page> 

我正在尝试登录并返回主页,如果成功,则返回LoginPage,如果不使用generics。

我有一个基类,Page由SecuredPage扩展,用于登录墙后面的页面。 我编写了一个通用的辅助方法来构造任何类型的页面。 LoginPage上的登录方法使用此方法。 LoginPage扩展页面和HomePage扩展SecuredPage。 SecuredPage扩展了Page。 如果返回LoginPage,则登录方法有效,但是在尝试返回HomePage时出现上述错误。 由于HomePage是页面的子类,因为它的父类扩展了Page,所以我很困惑为什么HomePage不能有效替代有界参数<T extends Page>

 public abstract class Page<T extends Page> extends SlowLoadableComponent { protected static final <T extends Page> T constructPage(WebDriver driver, int timeoutInSeconds, java.lang.Class pageClass) { Page p = null; try { Constructor pageConstructor = pageClass.getConstructor( WebDriver.class, String.class, Integer.TYPE); p = pageConstructor.newInstance(driver, driver.getCurrentUrl(), timeoutInSeconds); p.get(); } catch(Exception e) { } return pageClass.cast(p); } } 

这是SecuredPage类:

 public class SecuredPage extends Page { ..... } 

这是主页:

 public final class HomePage extends SecuredPage { ...... } 

这是LoginPage:

 public final class LoginPage extends Page { public final HomePage loginWithGoodCredentials(final User user) { return login(user, HomePage.class); } public final LoginPage loginWithBadCredentials(final User user) { return login(user, LoginPage.class); } public final <T extends Page> T login(final User user, final Class expectedPage) { enterUsername(user.getUsername()); enterPassword(user.getPassword()); loginButton.click(); return Page.constructPage(getDriver(), getTimeoutInSeconds(), expectedPage); } } 

问题是HomePagePage而不是Pagelogin方法将从其通用签名返回Page

您必须使HomePage的generics参数与其自身相关,而不是与SecuredPage 。 这将解决编译器错误。 保持SecuredPage通用,但要确保其绑定扩展SecuredPage 。 然后为HomePage中的generics参数T分配HomePage

 class SecuredPage> extends Page { ... } class HomePage extends SecuredPage { ... } 

调用login(user, SecuredPage.class)有效,但login(user, HomePage.class)却没有。 原因是: SecuredPage类型参数TSecuredPageHomePageSecuredPage的子类,因此HomePageT类型参数也是SecuredPage

现在,您使用Page调用login 。 但是这样的课程并不存在。 HomePagePage的子类。

如果您仍希望HomePage在存在Bounded Generics的情况下扩展SecuredPage ,请将“ Generic Substitution ”传递给HomePage。

不要在SecuredPage替换Generic ,而是将SecuredPage

 public class SecuredPage> extends Page { } 

在创建HomePage ,声明这样的generics值,

 public class HomePage extends SecuredPage { } 

这应该基本上解决了错误

出于constructPage方法的目的,您可以使用

 protected static final > T constructPage(...) { Page p = null; //... }