绑定不匹配错误和java泛型方法

时间:2013-04-08 16:06:30

标签: java generics selenium-webdriver

我收到以下错误:

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

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

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

public abstract class Page<T extends Page<T>> extends SlowLoadableComponent<T> {

    protected static final <T extends Page<T>> T constructPage(WebDriver driver, 
    int timeoutInSeconds, java.lang.Class<T> pageClass) 
    {
        Page<T> p = null;

        try {
            Constructor<T> 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<SecuredPage> {

    .....
}

这是主页:

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

这是LoginPage:

public final class LoginPage extends Page<LoginPage>  {


    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>> T login(final User user, final Class<T>     
            expectedPage) {
        enterUsername(user.getUsername());
        enterPassword(user.getPassword());
         loginButton.click();

        return Page.constructPage(getDriver(), getTimeoutInSeconds(), 
        expectedPage);
    }
}

5 个答案:

答案 0 :(得分:6)

问题是HomePagePage<SecuredPage>而不是Page<HomePage>login方法将从其通用签名返回Page<HomePage>

您必须使HomePage的通用参数与其自身相关,而不是SecuredPage。这将解决编译器错误。保持SecuredPage通用,但请确保其范围扩展SecuredPage<T>。然后为HomePage中的通用参数T指定HomePage

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

答案 1 :(得分:2)

调用login(user, SecuredPage.class)有效,但login(user, HomePage.class)没有。原因是:T中的类型参数SecuredPageSecuredPageHomePageSecuredPage的子类,因此T的{​​{1}}类型参数也是HomePage

现在,您使用SecuredPage致电login。但是这样的课程并不存在。 Page<HomePage>HomePage的子类。

答案 2 :(得分:1)

如果您仍希望HomePage在存在 Bounded Generics 的情况下展开SecuredPage,请传递'通用替换< / em>'直到主页。

请勿在{{1​​}}替换 通用 ,而应将SecuredPage替换为

SecuredPage

并在创建public class SecuredPage<T extends Page<T>> extends Page<T> { } 时,声明此类通用的值,

HomePage

这应该基本上解决错误

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

如果您仍然遇到相同的错误,请从以下位置更改JDK 1.8或编译器级别的最新版本: 窗口>首选项> Java>编译器>“编译器编译级别”-> 1.8