2012-03-04 22 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