Java Generics是否有办法采用需要实现2个接口的Generic参数?

时间:2009-07-17 01:16:01

标签: java generics interface

说我有这个代码 -

public interface ParentInterface1 {
    public List<? extends ChildInterface1> getChildren();
    public void setChildren(List<? extends ChildInterface1> children);
}
public interface ParentInterface2 {
    public List<? extends ChildInterface2> getChildren();
    public void setChildren(List<? extends ChildInterface2> children);
}
public interface ChildInterface1 {
    public String getField();
    public void setField(String field);
}
public interface ChildInterface2 {
    public String getField();
    public void setField(String field);
}
public class LParentImpl implements ParentInterface1, ParentInterface2 {
    private List<ChildImpl> list;
    public List<ChildImpl> getChildren() {
        return list;
    }
    public void setChildren(List<... wants to accept ChildImpl, which 
                                   implements ChildInterface1 & ChildInterface2> children) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
public class ChildImpl implements ChildInterface1, ChildInterface2 {
    private String field;
    public String getField() {
        return field;
    }
    public void setField(String field) {
        this.field = field;
    }
}

有没有办法让ParentImpl类中的setChildren()工作,而不从接口和实现中完全删除Generic类型?

我想做像 -

这样的事情
public void setChildren(List<? extends ChildInterface1 & ChildInterface2> children) 

这种接口/实现结构对非泛型类型有效,但似乎泛型的运行时擦除的某些方面可能会使这变得不可能?或者我错过了一些神奇的语法?

编辑:使用列表&lt;?扩展ChildInterface1&amp; ChildInterface2&GT;产生此编译错误 -

...\ParentImpl.java:20: > expected
    public void setChildren(List<? extends ChildInterface1 & ChildInterface2> children) {

4 个答案:

答案 0 :(得分:11)

您可以指定一个方法来获取实现这两个接口的对象:

public <T extends IFirst & ISecond> void doSomething(T obj) {}

但是,在您的示例中并不重要,因为您的子接口都指定了相同的方法。

答案 1 :(得分:4)

你可以这样做:

public class MyClass<T extends ChildInterface1 & ChildInterface2> { ... }

查看Java Generics Wildcarding With Multiple Classes

答案 2 :(得分:4)

你的问题没有意义。

ParentInterface1.setChildren接受List<ChildInterface1>。因此LParentImpl.setChildern这么多,但是你试图限制它以便它不会。

您可能想说,参数化ParentInterface1 / 2,但我建议尽可能避免多重继承接口(不仅仅涉及泛型的地方)。

答案 3 :(得分:0)

这不是答案,但我要感谢Jorn的回答!

当我试图完全按照你的答案给我的时候,我偶然发现了这个帖子(尽管它没有回答原来的提问者)。我试着这样做:

public static interface Displayable
    extends Identifiable, Nameable { }

public void print(Displayable obj) {
    System.out.println("[" + obj.getIdentity() + "] " + obj.getName());
}

不起作用,因为我传递的对象没有实现Displayable,但没有单独实现Nameable和Identifiable。

使用Jorn的技术,我这样做:

public <T extends Identifiable & Nameable> void print(T obj) {
    System.out.println("[" + obj.getIdentity() + "] " + obj.getName());
}

它完美无瑕!

我希望这会对那些遇到类似问题的人有所帮助(并且偶然发现了这个问题)。