2012-03-04 52 views
0

我在使用泛型和接口列表時遇到了問題。使用泛型在列表中鑄造對象

我有一個接口Comment,它由類CommentNews擴展。

評論:

public interface Comment { 

    public static final String COMMENT_NEWS_PATH = "/comment/news"; 
    public static final String COMMENT_EVENT_PATH = "/comment/event"; 
    public static final String COMMENT_GROUP_PATH = "/comment/group"; 

    public User getUser(); 

    public void setUser(User user); 

    public String getText(); 

    public void setText(String text); 

    public Date getModified(); 

    public void setModified(Date modified); 

    public void setCommentsList(List<?> commentsList); 

    public <T extends Comment> List<T> getCommentsList(); 
} 

CommentNews:

public class CommentNews implements Comment { 

    private Integer id; 
    private User user; 
    private News news; 
    private String text; 
    private List<CommentNews> commentsList; 

    public CommentNews() {} 

    // Methods snipped for brevity 

    public List<CommentNews> getCommentsList() { 
     return commentsList; 

    } 

    public void setCommentsList(List<?> commentsList) { 
     this.commentsList = (List<CommentNews>) commentsList; 

    } 
} 

的問題是與setCommentsList方法,類投實際上並不在列表中投的每個對象。我無法更改方法簽名,因爲這會與接口產生名稱衝突。

有沒有辦法使用泛型進行鑄造?我想避免遍歷列表並手動投射每個對象。

UPDATE: 如果我改變註釋界面。如果我的界面

public <T extends Comment>void setCommentsList(List<T> commentsList); 

和CommentNews類更改爲

public void setCommentsList(List<CommentNews> commentsList) { 
     this.commentsList = commentsList; 
    } 

它應該是類型安全的,但是這導致名稱在界面和類之間發生衝突。

+0

每個對象都會施放什麼?演員陣容不會改變任何對象。通過執行轉換可能發生的唯一情況是ClassCastException。 – 2012-03-04 12:19:01

回答

3

基本上,您的界面不是類型安全的。沒有什麼從做這樣的事情阻止別人:

Comment comment = ...; // Wherever 
List<Integer> numbers = new List<Integer>(); 
numbers.add(10); 
comment.setCommentsList(numbers); 

真的要允許嗎?

可能有一個列表包裝,每當它被訪問時執行轉換(而不是預先),但它會更好地改變接口。

編輯:如果你想任何評論,只持有相同類型的子評論,你可能想使你的Comment接口通用的,就像這樣:

public interface Comment<T extends Comment<T>> { 

    // Note: no public modifier; it's allowed by the spec but discouraged 
    void setCommentList(List<T> comments); 
    List<T> getCommentList(); 
} 

(你仍然可以使用通配符如果你想,但你可能不需要,而且會使事情複雜化。)

+0

查看我的更新回答:) – j0ntech 2012-03-04 12:24:47

+0

@olivervaga:你的意思是問題:)但不清楚你爲什麼要'CommentNews'對接口有不同的方法簽名。它肯定能夠通過任何形式的評論來處理對setComments的調用?如果沒有,這聽起來像你可能想要一個遞歸的泛型定義。將編輯我的答案。 – 2012-03-04 12:27:52

+0

遞歸泛型定義是一個很好的提示,但是我現在發現我的問題來自於我正在使用的REST客戶端。儘管如此,我仍然接受這個答案,因爲它仍然適用......種類。 – j0ntech 2012-03-04 12:47:13