sha*_*sir 7 java generics collections
假设我有一个接口和一些类:
public interface IPanel<ComponentType extends Component> {
   public void addComponents(Set<ComponentType> components);
   public ComponentType create();
}
public class Button extends Component { }
public class LocalizedButton extends Button { }
public class ButtonsPanel implements IPanel<Button> {
    public void addComponents(Set<Button> components) { ... /* uses create() */ ; }
    public Button create() { return new Button(); }
}
public class LocalizedButtonsPanel extends ButtonsPanel {
    public Button create() { return new LocalizedButton(); }
}
Run Code Online (Sandbox Code Playgroud)
然后我有一组LocalizedButtons,当我打电话
final LocalizedButtonsPanel localizedButtonsPanel = new LocalizedButtonsPanel();
final Set<LocalizedButton> localizedButtonsSet = new LinkedHashSet<LocalizedButton>();
localizedButtonsPanel.addComponents(localizedButtonsSet);
Run Code Online (Sandbox Code Playgroud)
我知道这个方法不适用于这个参数.如果我尝试过载这种方法addComponents(Set<LocalizedButton> buttons)中LocalizedButtonsPanel,我得到的当然是类型擦除.
可能是某些模式被遗漏或存在处理此架构以实现正确添加LocalizedButtons集的技巧?
我得到了答案,我想让我的例子更具体 - 我的实现中有一些验证器,所以我需要将集合类型也存储为通用,这是我使用答案得到的简化代码:
public interface IPanel<ComponentType extends Component, CollectionType extends Collection<? extends Component>> extends Validated<CollectionType> {
   public void addComponents(CollectionType components);
   public ComponentType create();
}
public class Button extends Component { }
public class LocalizedButton extends Button { }
public class ButtonsPanel implements IPanel<Button, Set<? extends Button>> {
    public void addComponents(Set<? extends Button> components) { ... /* uses create() */ ; }
    public Button create() { return new Button(); }
}
public class LocalizedButtonsPanel extends ButtonsPanel {
    public Button create() { return new LocalizedButton(); }
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它的工作原理
将addComponents()签名更改为
public void addComponents(Set<? extends Button> components)
Run Code Online (Sandbox Code Playgroud)
这样方法接受Button的子类集.这样,您可以传递一个Set<LocalizedButton>参数,因为LocalizedButtonextends Button和因此匹配参数Type of Set<? extends Button>.
你有
public class ButtonsPanel implements IPanel<Button> {
    public void addComponents(Set<Button> components) { ... /* uses create() */ ; }
    public Button create() { return new Button(); }
}
Run Code Online (Sandbox Code Playgroud)
应该
public class ButtonsPanel implements IPanel<Button> {
    public void addComponents(Set<? extends Button> components) { ... /* uses create() */ ; }
    public Button create() { return new Button(); }
}
Run Code Online (Sandbox Code Playgroud)
该列表仅针对不适用于扩展该类型的Object的按钮类型创建.