【问题标题】:Implementing a generic container for a list of interface instances in Java在 Java 中为接口实例列表实现通用容器
【发布时间】:2020-03-15 08:45:37
【问题描述】:

这里是 Java 8。我有以下 POJO:

public interface HasPartNumber {
  String getPartNumber();
}

@Getter
@Setter
public class InventoryItem implements HasPartNumber {
  private String modelNumber;
  private String description;
  // lots of other fields here

  @Override
  public String getPartNumber() {
    return this.modelNumber;
  }
}

public class Inventory extends ArrayList<InventoryItem> {
  // Inventory is just an alias of a list of InventoryItem
}

@Getter
@Setter
public class PriceItem implements HasPartNumber {
  private String equipmentNumber;
  // lots of other fields here

  @Override
  public String getPartNumber() {
    return this.equipmentNumber;
  }
}

public class PriceRoster extends ArrayList<PriceItem> {
  // PriceRoster is just an alias of a list of PriceItem
}

理解你们中的一些人可能不喜欢我如何建模InventoryPriceRoster,但使用 is-a 和 has-a 黄金法则是正确的。 “库存”不仅仅是InventoryItems 的列表。 PriceRoster 同上。而且,Domain-Driven Design 社区可能会同意这些是有效的数据模型,如果对阅读代码的开发人员有意义的话。

然而,我并没有结婚这种设计。因此,虽然我的建议是将这个数据模型保持在上面,但如果真的不可能在不更改数据模型的情况下完成我在下面描述的内容,我会很灵活。


我正在尝试编写一个通用的PartProcessor 类,它将遍历HasPartNumber impls 的列表并对它们执行处理。我的最佳尝试:

public class PartProcessor<PART_CONTAINER extends List<HasPartNumber>> {

  public void process(PART_CONTAINER partContainer) {

    partContainer.stream().forEach(part -> {

      // Do something here

    });

  }

}

当我去实例化PartProcessor时产生编译错误:

PartProcessor<Inventory> inventory = new PartProcessor<Inventory>();

我看到的编译器错误是:

"类型参数 'com.example.myapp.Inventory' 不在其范围内;应实现 'java.util.List'"

有什么想法可以让我的PartProcessorHasPartNumbers impl 的任何列表上通用,包括InventoryPriceRoster

【问题讨论】:

    标签: java generics collections java-8


    【解决方案1】:

    有界类型使类型协变

     public class PartProcessor<PART_CONTAINER extends List<? extends HasPartNumber>> {... 
    

    如需更广泛的阅读,请参阅this answer also

    【讨论】:

    • 感谢@Eugene (+1),但我可以将PartProcessor 放在它自己的源文件(PartProcessor.java) 中吗?这样做会产生编译器错误:“Modifier 'static' not allowed here”...
    • @hotmeatballsoup 当然可以,但我猜不出到底是什么不适合你。
    • 根据this 你不能有一个顶级的静态类
    • @hotmeatballsoup 啊!对,一个顶级类——不;但你不需要它,对吧?
    • 我的意思是,我宁愿让它成为顶级课程......我还能把它放在哪里?!它适用于所有HasPartNumbers 列表。所以对我来说,把它放在Inventory.javaPriceRoster.java 里面是没有意义的。而HasPartNumber 只是一个单一方法的接口......所以把它放在里面对我来说也很奇怪!
    猜你喜欢
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    相关资源
    最近更新 更多