2013-04-08 12 views
5

otrzymuję następujący błąd:Związane błąd niedopasowania i java rodzajowy metoda

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>> 

Próbuję zrobić login i powrócić do strony głównej, jeśli się powiedzie i LoginPage jeśli nie używając rodzajowych.

Mam klasę podstawową, stronę rozszerzoną o SecuredPage dla stron za ścianą logowania. Napisałem ogólną metodę pomocniczą, która tworzyłaby strony dowolnego typu. Ta metoda jest używana przez metodę logowania na stronie logowania. LoginPage extends Page i HomePage rozszerza SecuredPage. SecuredPage rozszerza stronę. Metoda logowania działa, gdy strona Login jest zwracana, ale otrzymuję powyższy błąd, próbując zwrócić stronę główną. Ponieważ HomePage jest podklasą strony, ponieważ jej klasa nadrzędna rozszerza stronę, nie rozumiem, dlaczego HomePage nie jest poprawnym substytutem ograniczonego parametru <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);  
    } 
} 

Jest to klasa SecuredPage:

public class SecuredPage extends Page<SecuredPage> { 

    ..... 
} 

A to Homepage:

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

To 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); 
    } 
} 
+0

oprawionego klasie 'stronę >' prawie nigdy nie jest przydatny w Javie – newacct

Odpowiedz

6

Problem polega na tym, że HomePage to Page<SecuredPage>, a nie Page<HomePage>. Metoda login zwróci Page<HomePage> ze swojej ogólnej sygnatury.

Musisz podać ogólny parametr związany ze sobą, HomePage, a nie SecuredPage. Spowoduje to rozwiązanie błędu kompilatora. Zachowaj ogólną nazwę SecuredPage, ale upewnij się, że jej granica rozszerza się o SecuredPage<T>. Następnie przypisz sam HomePage do ogólnego parametru T w HomePage.

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

Dzięki. To działa! – Selena

2

Wywołanie login(user, SecuredPage.class) działa, ale login(user, HomePage.class) nie. Powodem jest: parametr typu T w SecuredPage jest SecuredPage. HomePage jest podklasą SecuredPage, więc parametr typu z HomePage jest również SecuredPage.

Teraz dzwonisz pod numer login z numerem Page<HomePage>. Ale taka klasa nie istnieje. HomePage jest podklasą Page<SecuredPage>.

+0

tak, to co muszę zrobić w klasie deklaracja dla SecuredPage, aby to działało? Nie jestem super doświadczony z generykami, oczywiście .... – Selena

+0

Czy coś takiego ma rację: klasa publiczna SecuredPage > rozszerza Page , a następnie HomePage może być: public class HomePage extends SecuredPage ? – Selena

+0

Wszystkie nadklasy muszą mieć parametr ogólny "T", tylko konkretne klasy podklas mogą mieć typ powtarzalny. Wdrożyłbym 'AbstractSecuredPage ' i ostateczną klasę 'SecuredPage'. –

1

Jeśli nadal chcesz HomePage przedłużyć SecuredPage z obecnością Bounded Generics, prosimy przejść 'Generic Zmiana' do głównej.

nie zastępują Generic w SecuredPage, zamiast uczynić SecuredPage jak

public class SecuredPage<T extends Page<T>> extends Page<T> { 

} 

i podczas tworzenia HomePage, zadeklarować wartość dla rodzajowy tak,

public class HomePage extends SecuredPage<HomePage> { 

} 

ten powinien zasadniczo rozwiązać błąd

1

Dla celów metodę constructPage, można po prostu użyć

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

Dzięki za to. Chciałbym móc przyjąć dwie odpowiedzi, ponieważ twoja odpowiedź pokazuje coś o rodzajach, które zabrały mnie na zawsze. – Selena

Powiązane problemy