2013-12-09 164 views
4

有幾個簡單的測試用例類:Java泛型,說明需要

public interface ListCriteria<T> { 
    // some stuff here 
} 

public class UserListCriteria implements ListCriteria<User> { 
// implementation 
} 

public interface Editor<T> { 
    // sample method 1 
    List<T> listObjectsTest1(ListCriteria<T> criteria); 
    // sample method 2 
    <L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria); 
} 

而且有大量Editor實現的Java認爲它不適用於這兩種樣品的方法提供必要的實施:

public class UserEditor implements Editor<User> { 

    @Override 
    public List<User> listObjectsTest1(UserListCriteria criteria) { 
    // 
    } 

    @Override 
    public List<User> listObjectsTest2(UserListCriteria criteria) { 
    // 
    } 
} 

這兩種方法的實現都是錯誤的。問題是爲什麼。特別是對於後一種方法。 當然我可以做interface Editor<T, L extends ListCriteria<T>>,這將解決這個問題,但我不想,我想明白爲什麼我不能在這裏使用方法級別的泛型。

回答

2

您得到的錯誤與泛型沒有任何關係,因爲您使用另一種類型的接口實施該方法。

Editor接口定義

List<T> listObjectsTest1(ListCriteria<T> criteria); 

因此UserEditor必須在你的情況

public List<User> listObjectsTest1(ListCriteria<User> criteria) { 

實現你不應該犯的錯誤參數與參數的泛型類型的類型。 Editor接口強制執行ListCriteria類型。 ListCriteria的通用類型是TT可以由子類綁定,例如implements ListCriteria<User>。這就是我的意思,當我說「你得到的錯誤與泛型無關」

我猜你想要什麼

public interface Editor<C, T extends ListCriteria<C>> { 
    List<C> listObjectsTest1(T criteria); 
} 

,然後UserEditor可以實現爲

public class UserEditor implements Editor<User, UserListCriteria> { 

    public List<User> listObjectsTest1(UserListCriteria criteria) { 
     return null; 
    } 
} 

爲什麼呢?特別是對於後一種方法

Editor界面第二種方法

<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria); 

並不意味着你可以實現任何類型的L 結合UserEditor仍然必須執行

public <L extends ListCriteria<User>> List<User> listObjectsTest2(L criteria) { 
    return null; 
} 

該方法定義了一個通用類型L,它將在cl客戶調用該方法。 因此,您可以調用任何類型爲ListCriteria<User>的子類型的方法。

+0

謝謝,我能得到你的權利,說我可以覆蓋的返回類型,而不是方法的參數,即使'UserListCriteria'完全在運行時符合,我必須堅持以完全相同的ARG簽名? – Osw

+0

@Osw我更新了答案,並希望現在更清楚 –

1
  1. listObjectsTest1(UserListCriteria criteria)UserEditor功能不重寫Editor<T>接口listObjectsTest1(ListCriteria<T> criteria)的功能,因爲他們有兩個不同的簽名,即基本參數的類型。

  2. 這同樣適用於listObjectsTest2這是在接口中聲明:<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria);但你已經宣佈它在UserEditor類爲:List<User> listObjectsTest2(UserListCriteria criteria)

所以,你需要將簽名改爲:

class UserEditor implements Editor<User> { 


    @Override 
    public List<User> listObjectsTest1(ListCriteria<User> criteria) { 

    } 

    @Override 
    public <L extends ListCriteria<User>> List<User> listObjectsTest2(L criteria) { 

    } 
} 

請有關詳細信息,通讀jls 8.4.8. Inheritance, Overriding, and Hiding