具有类型安全实现的 Java 泛型接口

2023-12-26

我正在寻找从通用框架调用特定接口的良好替代方案。我用代码来举例说明。看看问题部分,包含示例代码主要是为了彻底性,并将示例应用到实际场景中。

Example

假设我们想要基于组件列表构建报告。假设我们有两种特定的组件类型:

public interface Component { ... }
public class PDFComponents extends Component { ... }
public class WordComponents extends Component { ... }

每个组件都有一个 ReportBuilder 实现,例如,

public interface ReportBuilder { ... }
public class PDFReportBuilder extends ReportBuilder { ... }
public class WordReportBuilder extends ReportBuilder { ... }

哪个构建具体的报告实现

public interface Report { ... }
public class PDFReport extends ReportBuilder { ... }
public class WordReport extends ReportBuilder { ... }

最后,我们提供了定位组件并根据组件生成报告的服务。

public class ReportService {
    ReportComponentRepository repo;
    List<ReportBuilder> builders;

    public <T extends Report> T getReport(Class<T> reportType) {
        // Get report components. E.g., this might return List<PDFComponent>
        List<Component> reportComponents = repo.getReportComponents(id);

        // Build report from components using one of the registered builders
        for (ReportBuilder builder : builders) {
            if (builder.buildFor(reportType) {
                return builder.buildReport(report);
            }
        }
    }
}

使用服务的示例

List<PDFReport> reports = new ReportService().getReport(PDFReport.class);

Question

现在回答问题。如何设计一个通用的 ReportBuilder 接口,使其实现具有类型安全性?

例如,选择接口:

public Report buildReport(List<? extends Component> components);

会导致其实现的丑陋:

public class PDFReportBuilder implements ReportBuilder {

    @Override
    public Report buildReport(List<? extends Component> components) {
         PDFReport report;

         for (Component component : components) {
            if (component instanceOf PDFComponent) {
                // assemble report ... 
                report.includeComponent(component);
            }
        }

        return report;
    }
}

当我们真正希望 PDFReportBuilder 的界面为例如:

 public Report buildReport(List<PDFComponent> component) { ... }

如果将 Component 的类型设置为 ReportBuilder 的类型变量,则它会起作用:

public interface ReportBuilder<T extends Component> {
    public Report buildReport(List<T> components);
}

public class PDFReportBuilder implements ReportBuilder<PDFComponent> {
    public Report buildReport(List<PDFComponent> components);
}

不过,您必须评估是否确实需要 ReportBuilder 中的类型变量。这并不总是正确的选择。另外,如果您还想要PDFReportBuilder.buildReport要具有 PDFReport 的返回类型,那么您还需要将其作为类型变量(即,public interface ReportBuilder<T extends Component, S extends Report>).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有类型安全实现的 Java 泛型接口 的相关文章

  • 如何在 Java 中访问嵌套的 HashMap?

    我有一个 Java 中的 HashMap 其中的内容 你们可能都知道 可以通过以下方式访问 HashMap get keyname 如果一个 HashMap 位于另一个 HashMap 中 即嵌套的 HashMap 我将如何访问内容 我可以
  • 将一种类型的对象声明为另一种类型的实例有什么好处? [复制]

    这个问题在这里已经有答案了 可能的重复 Base b2 new Child 是什么意思 表示 https stackoverflow com questions 4447924 what does base b2 new child sig
  • Quarkus 不以编程方式选择 bean

    我试图以编程方式选择 bean 但 quarkus 不会注入 bean 并引发异常 不支持吗 public enum ReportType ONE TWO Qualifier Retention RUNTIME Target METHOD
  • 在命令行java中突出显示文本[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一项任务是重新创建 unix cal 程序 除了一部分之外 相当简单 今天 它突出显示了该数字 我不知道该怎么做 关于如何在 Ja
  • 如何在Java中优雅地处理SIGKILL信号

    当程序收到终止信号时如何处理清理 例如 我连接到一个应用程序 希望任何第三方应用程序 我的应用程序 发送finish注销时的命令 发送该信息最好说什么finish当我的应用程序被破坏时的命令kill 9 编辑1 kill 9无法被捕获 谢谢
  • OpenNLP 与斯坦福 CoreNLP

    我一直在对这两个包进行一些比较 但不确定该往哪个方向走 我简单地寻找的是 命名实体识别 人 地点 组织等 性别识别 一个不错的训练 API 据我所知 OpenNLP 和斯坦福 CoreNLP 提供了非常相似的功能 然而 Stanford C
  • Kafka Java Consumer 已关闭

    我刚刚开始使用卡夫卡 我面临着消费者的一个小问题 我用Java写了一个消费者 我收到此异常 IllegalStateException 此消费者已关闭 我在以下行中遇到异常 ConsumerRecords
  • 在 Junit 测试中使用 ReflectionTestUtils.setField()

    我是 JUnittesting 的新手 所以我有一个问题 谁能告诉我为什么我们使用ReflectionTestUtils setField 在我们的 Junit 测试示例中 正如评论中提到的 java 文档很好地解释了用法 但我还想给你们举
  • 正则表达式在 Velocity 模板中不起作用

    我在 Test java 中尝试过这个 String regex lt s br s s gt String test1 lt br gt System out println test replaceAll regex 但是当我在速度模板
  • Android volley使用RequestFuture.get()时出现超时异常

    在我的片段中 我尝试使用 TMDB 的开放电影数据库来获取有关 正在播放 电影的详细信息 如果我使用 RequestFuture get time TimeUnit 方法来执行此齐射请求 我总是会收到超时错误 如果我在 Safari 中手动
  • Java - JPanel 内有边距和 JTextArea

    我想创建这样的东西 主面板有其边距 x 并且 TextArea 位于该面板的中心 几乎填满了面板 底部是另一个具有自定义尺寸 高度 y 的面板 可以使用某些快捷方式将其切换为可见和不可见 底部面板有 FlowLayout 和几个元素 问题是
  • java.lang.Object的hashCode具体使用的算法是什么

    中使用的算法是什么JVM实施java lang Object的隐含的hashCode 方法 OpenJDK or Oracle JDK答案中首选 它依赖于实现 并且在很大程度上 该算法是entirely取决于实施 只要它是一致的 但是 根据
  • 从 HttpClient 3 转换为 4

    我已经成功地对所有内容进行了更改 但以下内容除外 HttpClient client HttpPost method client new DefaultHttpClient method new HttpPost url InputStr
  • 如何在 Bean Validation 1.0 中构造 ConstraintViolationException?

    我对 javax validation API 感到困惑 我正在编写一个简单的测试来理解它 Sample sample new Sample Set
  • 配置jmxremote时无法正常停止tomcat

    我添加了一个jmxremotecatalina bat中的配置 set JAVA OPTS Dcom sun management jmxremote port 9004 Dcom sun management jmxremote ssl
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • Java和手动执行finalize

    如果我打电话finalize 在我的程序代码中的一个对象上 JVM当垃圾收集器处理这个对象时仍然再次运行该方法吗 这是一个大概的例子 MyObject m new MyObject m finalize m null System gc 是
  • Java:一个函数有多种返回类型...可以使用泛型吗?

    为了简单起见 我有一些程序 如下所示 public String fetchValueAsString String key public DateTime fetchValueAsDateTime String key 我想要类似的东西
  • android 中的 java.net.URL ..新手问题

    我是java新手 正在尝试android开发 以下代码生成 malformedURLException 有人可以帮助我识别异常吗 任何提示都会非常有帮助 package com example helloandroid import and
  • 如何使用注释处理 Hibernate 和 Spring 中的连接查询?

    我正在使用 Spring 和 Hibernate 以及 MySQL 开发应用程序 我是 Hibernate 新手 完成了基本任务 现在我需要在选择查询中应用联接以使用注释从多个表中获取数据 我已经搜索过但仍然没有任何想法 这是我的数据库表和

随机推荐

  • Perl 正则表达式限制的解决方法?

    我编写了一个程序来从邮件文件夹中提取附件 GITHUB https github com barrycarter bcapps blob master bc extract attachments pl 但由于 Perl 对正则表达式匹配的
  • Angular 2 AOT 构建错误 - JavaScript 堆内存不足

    我的 Angular 2 应用程序是由angular2 webpack 启动器 https www npmjs com package angular2 webpack starter 当我运行命令时npm run build aot构建A
  • pandas 上的数据框划分系列

    我需要划分矩阵的每一列df1进入矩阵的单列df2 得到一个有维数的矩阵df1 3 2 我需要一个结果 dataframe 1 6 2 7 3 8 3 6 4 7 5 8 df1 pd DataFrame data 1 2 3 3 4 5 i
  • 在批处理文件中逐行读取txt

    这是我的问题 我有一个 txt 文件 其中包含 100 个不同的视频名称 示例 abc mpg def mpg ghi mpg xyz mpg 我想使用一些命令逐一处理这些视频 并将结果放入同名的文件夹中 不带扩展名 command1 ab
  • 收集硬币并添加到 Sprite Kit 中的分数标签

    我正在尝试使用本教程作为参考 在我的游戏中实现一个简单的评分系统 http www raywenderlich com 87232 make game like mega jump sprite kit swift part 2 http
  • TagLib Sharp 不编辑艺术家

    我正在尝试将新的艺术家和标题 id3 标签保存到曲目中 从曲目加载标签工作正常 编辑曲目标题也工作正常 但是当我尝试编辑时演员 artist 它没有改变任何东西 这是代码 public void renameID3 string artis
  • 由于弃用而替换 self->isa

    我刚刚安装了 Xcode 4 6 现在我管理的古老代码中出现了新错误 编译器抱怨 直接访问 Objective C 的 isa 已被弃用 取而代之的是 object setClass 和 object getClass 并且该项目将无法构建
  • 如果 Vue 3 引用是对象的属性,则它们的行为会有所不同

    使用 Vue 3 的 Composition API 时 我注意到模板内部的引用在作为对象的属性进行访问时的行为有所不同 我认为这是最好的总结SFC Playground 中的这个示例 https sfc vuejs org eyJBcHA
  • F# 结构元组与 BCL 元组类型

    在 F 中你可以定义一个first函数如下 let first x y x 你可以这样称呼它 first 1 2 您还可以根据 BCL 定义相同的函数Tuple type let first t Tuple lt gt t Item1 但是
  • 如何使用 Github Actions 和语义发布 Github 插件发布整个目录?

    我想使用语义发布在 Github 版本上发布整个目录 构建目录 但不幸的是它将每个构建文件作为单个资产发布 对于复制 我正在使用 Vue CLI 生成项目vue create foo 安装语义释放作为开发依赖项npm install sav
  • 使用 VSTS 发布定义的蓝/绿部署

    我还没有看到任何有关如何在 VSTS 发布定义上进行蓝 绿部署的信息 我有一个 VSTS 发布定义 当我们的源代码中完成新的签入时 它会自动将新的更改部署到我们的 Prod 环境中 现在 该项目正在使用 Azure 流量管理器 并且添加了位
  • 枚举反向查找[重复]

    这个问题在这里已经有答案了 假设我有一个枚举 enum Color Red 1 Green Blue 如果我有一个号码 我可以通过这样做来获取枚举键 var colorName string Color 2 colorName Green
  • Python中使用os.walk()递归遍历目录

    我想从根目录导航到其中的所有其他目录并打印相同的内容 这是我的代码 usr bin python import os import fnmatch for root dir files in os walk print root print
  • ActiveModel::匿名类的验证

    我正在开发一个类似 DataMapper 的小型 ODM 项目 并且我正在尝试利用ActiveModel Validations成分 然而 我在编写测试时遇到了问题 我使用匿名类来构建我的测试模式 但是当涉及到运行验证器时 ActiveMo
  • 将 std::string ** 转换为 char *** 并且它恰好可以工作。如何?

    考虑以下代码 std vector
  • Python读取格式化字符串

    我有一个包含多行的文件 其格式如下 FIELD POSITION DATA TYPE COOP ID 1 6 Character LATITUDE 8 15 Real LONGITUDE 17 25 Real ELEVATION 27 32
  • jQuery 更改 iFrame 的内容

    我对使用 jQuery 完全陌生 为什么这不起作用 your browser needs to be updated 另外 我计划使用此 iFrame 向用户展示 html 文件更改的预览 我将在
  • Scala - 循环案例类名称以用作类型参数

    我在 Scala 代码 Scala 2 13 中有一个这样的函数 可以与 Spark 一起使用 def getDataset T lt Product TypeTag name String Dataset T import spark i
  • 运行TFS构建服务(NT AUTHORITY\NETWORK SERVICE)的帐户需要在发布管理服务器中添加为系统用户

    当我尝试从我的构建中触发发布时 我收到上述错误 构建可以自行运行 发布也可以自行运行 但我无法触发发布 我的问题是发布管理中没有系统用户这样的东西 存在一个服务用户 将上述用户设置为服务用户 它还被设置为发布管理器 它还位于 TFS 中的
  • 具有类型安全实现的 Java 泛型接口

    我正在寻找从通用框架调用特定接口的良好替代方案 我用代码来举例说明 看看问题部分 包含示例代码主要是为了彻底性 并将示例应用到实际场景中 Example 假设我们想要基于组件列表构建报告 假设我们有两种特定的组件类型 public inte