2013-04-08 24 views
5

Tôi nhận được lỗi sau:ràng buộc lỗi không phù hợp và java phương pháp chung

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

Tôi cố gắng để làm một tên đăng nhập và trả về một trang chủ, nếu thành công và một LoginPage nếu không sử dụng Generics.

Tôi có một lớp cơ sở, Trang được mở rộng bởi SecuredPage cho các trang phía sau tường đăng nhập. Tôi đã viết một phương thức trợ giúp chung để xây dựng các trang thuộc bất kỳ loại nào. Phương thức này được sử dụng bởi phương thức đăng nhập trên LoginPage. LoginPage mở rộng Page và HomePage mở rộng SecuredPage. SecuredPage mở rộng trang. Phương thức đăng nhập hoạt động nếu LoginPage được trả về, nhưng tôi nhận được lỗi trên khi cố gắng trả về một HomePage. Vì HomePage là một lớp con của trang vì lớp cha của nó mở rộng Trang, tôi nhầm lẫn là tại sao HomePage không phải là một thay thế hợp lệ cho tham số bị ràng buộc <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);  
    } 
} 

Đây là lớp SecuredPage:

public class SecuredPage extends Page<SecuredPage> { 

    ..... 
} 

Và đây là HomePage:

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

Đây là 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

một ràng buộc lớp 'trang >' là gần như không bao giờ hữu ích trong Java – newacct

Trả lời

6

Vấn đề là HomePagePage<SecuredPage> và không phải là Page<HomePage>. Phương thức login sẽ trả về một số Page<HomePage> từ chữ ký chung của nó.

Bạn phải đặt thông số chung là HomePage liên quan đến chính nó, chứ không phải SecuredPage. Điều này sẽ giải quyết lỗi trình biên dịch. Giữ SecuredPage chung chung, nhưng đảm bảo giới hạn của nó mở rộng SecuredPage<T>. Sau đó, chỉ định HomePage chính nó cho thông số chung T trong HomePage.

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

Cảm ơn. Những công việc này! – Selena

2

Calling login(user, SecuredPage.class) công trình, nhưng login(user, HomePage.class) thì không. Lý do là: nhập thông số T trong SecuredPageSecuredPage. HomePage là một phân lớp của SecuredPage, vì vậy thông số loại T của HomePage cũng là SecuredPage.

Bây giờ, bạn gọi số login với số Page<HomePage>. Nhưng một lớp như vậy không tồn tại. HomePage là một phân lớp của Page<SecuredPage>.

+0

Vì vậy, những gì tôi cần phải làm trong lớp khai báo cho SecuredPage để làm việc này? Tôi không phải là siêu kinh nghiệm với generics, rõ ràng .... – Selena

+0

Điều gì đó như thế này là đúng: public class SecuredPage > extends Page và sau đó HomePage có thể là: public class HomePage mở rộng SecuredPage ? – Selena

+0

Tất cả các siêu lớp phải có tham số chung 'T', chỉ các lớp con của lớp con cụ thể mới có thể có kiểu tự định kỳ. Tôi sẽ thực hiện một 'AbstractSecuredPage ' và một lớp cuối cùng 'SecuredPage'. –

1

Nếu bạn vẫn muốn HomePage để mở rộng SecuredPage với sự hiện diện của Bounded Generics, xin vui lòng vượt qua 'Generic Thay' đến Trang chủ.

Đừng thay Generic tại SecuredPage, thay vì làm cho SecuredPage như

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

} 

và khi tạo HomePage, kê khai giá trị cho chung như thế này,

public class HomePage extends SecuredPage<HomePage> { 

} 

này nên về cơ bản giải quyết lỗi

1

Theo mục đích của phương pháp constructPage của bạn, bạn chỉ có thể sử dụng

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

Cảm ơn vì điều này. Tôi ước tôi có thể chấp nhận hai câu trả lời bởi vì câu trả lời của bạn làm nổi bật một cái gì đó về generics mà đã cho tôi mãi mãi để có được. – Selena

Các vấn đề liên quan