Java泛型通配符问题

2024-03-09

在使用 Google Guava 优秀的 Multimap 时,我遇到了一些泛型问题。我有一个这样定义的类型处理程序

public interface Handler<T extends Serializable> {
    void handle(T t);
} 

在另一个类中,我定义了一个多重映射,它将字符串映射到处理程序的集合。

private Multimap<String, Handler<? extends Serializable>> multimap = 
    ArrayListMultimap.create();

现在,当我尝试使用多重映射进行操作时,我遇到了编译器错误。我的第一次尝试是这样的:

public <T extends Serializable> void doStuff1(String s, T t)  {
    Collection<Handler<T>> collection = multimap.get(s);
    for (Handler<T> handler : collection) {
        handler.handle(t);
    }
}

这导致了以下错误。

Type mismatch: cannot convert from Collection<Handler<? extends Serializable>> to Collection<Handler<T>>

后来,我尝试像这样编写代码

public void doStuff2(String s, Serializable serializable)  {
    Collection<Handler<? extends Serializable>> collection = multimap.get(s);
    for (Handler<? extends Serializable> handler : collection) {
        handler.handle(serializable); 
    }
}

不幸的是也失败了:

The method handle(capture#1-of ? extends Serializable) in the type Handler<capture#1-of ? extends Serializable> is not applicable for the arguments (Serializable)

任何帮助将不胜感激。谢谢。

Update:

我设法解决此问题的唯一方法是抑制编译器警告。给定以下处理程序:

public interface Handler<T extends Event> {
    void handle(T t);

    Class<T> getType();
}

我可以这样编写事件总线。

public class EventBus {

    private Multimap<Class<?>, Handler<?>> multimap = ArrayListMultimap.create();

    public <T extends Event> void subscribe(Handler<T> handler) {
        multimap.put(handler.getType(), handler);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void publish(Event event)  {
        Collection<Handler<?>> collection = multimap.get(event.getClass());
        for (Handler handler : collection) {
            handler.handle(event);
        }
    }
}

我想没有办法用更少甚至没有@SuppressWarnings 来处理这个问题?


问题是类型可能不同:

private Multimap<String, Handler<? extends Serializable>> multimap = 
ArrayListMultimap.create();

不允许您向多重贴图添加任何内容,因为您不知道什么?实际上代表。例如,你可以有一个Multimap<String, Handler<String>>并尝试添加一个Integer因为两者都实现了Serializable.

编辑:其实上面这段话有一点错误。您应该能够将处理程序添加到多重映射,但由于处理程序的类型参数未知,因此您将无法使用处理程序,请参见下文。

In your doStuff1方法你定义一个具体的参数T这可能是完全不同的事情。因此编译器无法确定此分配是否正确:Collection<Handler<T>> collection = multimap.get(s); (is T真的是从多重映射中获得的处理程序的类型吗? - 编译器不知道)。

您的第二种方法确实可以正确分配任务,但是handle()方法不起作用,因为你传递了一个Serializable这可以是任何东西(String, Integer,其他的东西)并且编译器仍然不知道处理程序的类型是否匹配(想象它是一个Handler<Number>你通过了String to doStuff2).

您有多种替代方案可以解决此问题,每种方案都有其自身的缺点:

  1. 只需使用Multimap<String, Handler<Serializable>>,这将允许你通过任何Serializable对象到处理程序
  2. 使用具体类型,例如Multimap<String, Handler<String>>,这将限制您仅使用字符串处理程序
  3. 在运行时获取处理程序的类型参数并进行强制转换,如果获取不对可能容易出错
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java泛型通配符问题 的相关文章

  • 在 Java 中重置 Graphics2D 对象

    我正在用 Java 尝试 Graphics2D 但像往常一样 我被困住了 P 问题是 假设我有这个代码 Graphics2D g Graphics2D this getGraphics Inside a JFrame g rotate Ma
  • Android 上的 setTimeOut() 相当于什么?

    我需要等效的代码setTimeOut call function milliseconds 对于安卓 setTimeOut call function milliseconds 您可能想查看定时任务 http developer andro
  • 如何从 .t​​xt 文件读取数据并将数据放入对象的数组列表中?

    到目前为止 我所写的内容是基于我目前对基本数组的了解 但我只是不明白如何使用数组列表 或如何从文件中读取 到目前为止我所写的内容有效 任何有助于修复我的代码以从文件中读取并使用数组列表的链接或建议将不胜感激 谢谢 public class
  • 使用 ScheduledExecutorService 安排每月任务

    我想在该月的某一天的特定时间安排一项任务 每次运行之间的间隔可以设置在 1 到 12 个月之间 在java中 可以使用ScheduledExecutorService以固定的时间间隔调度任务 既然一个月的天数不固定 那么如何实现呢 提前致谢
  • 仅使用 ServletContext 查找应用程序的 URL

    我正在使用 Spring MVC 编写一个 Java Web 应用程序 我有一个后台进程 它会遍历数据库并查找必须通过电子邮件发送给我的用户的通知 这些电子邮件需要包含应用程序的超链接 对于网络应用程序来说 这似乎是相当常见的模式 但我遇到
  • 用户“root”@“localhost”的访问被拒绝

    我正在尝试从数据库中获取记录 但我面临这个访问被拒绝的问题 我尝试了 Stack Overflow 上提到的其他解决方案 例如向用户授予权限 但没有任何效果 访问数据库的代码 public void service HttpServletR
  • 如何在Spring Security SAML示例中配置IDP元数据和SP元数据?

    我想处理 Spring Security SAML 为此 我开始探索Spring安全SAML http docs spring io spring security saml docs 1 0 x reference html chapte
  • 在 Java 和 PHP 之间加密/解密字符串

    我使用 AES 加密来加密和解密服务器端的 php 和 Android 应用程序 作为客户端 之间的字符串 PHP 中的加密字符串为 HaxRKnMxT24kCJWUXaVvqDHahzurJQK sYA4lIHql U 在 Java 中是
  • 如何对JConsole的密码文件的密码进行加密

    我正在使用 JConsole 访问我的应用程序 MBean 并使用 password properties 文件 但根据 Sun 的规范 该文件仅包含明文格式的密码 com sun management jmxremote password
  • 序言中不允许引用

    请帮我找到这个异常的原因 我使用以下罐子 core renderer jar itext paulo 155 jar 第一个文档 xhtml lt xml version 1 0 encoding UTF 8 gt lt DOCTYPE h
  • JFreeChart MeterPlot

    我目前正在用java做Agent项目 在某些时候 我需要显示一个仪表 例如 电池电量 我的程序中有 5 个代理 每个代理都会创建自己的带有名称的仪表图 但不知何故他们没有更新数据集 或者他们正在更新数据集 只是它没有显示在仪表图上 任何想法
  • GAE - Eclipse 中的开发服务器未更新?

    我在 Eclipse 上使用 Google AppEngine 开发服务器 我的本地网页似乎没有更新 直到我在开发服务器上进行了多次重新启动 使用 Eclipse 中的 运行 或 调试 按钮 我究竟做错了什么 基本流程是 更改 java 文
  • ObservableList 不更新 ArrayList

    对于学校作业 我们正在使用 JavaFX 中的 ObservableList 对象 对吗 我已经为此工作了一天多了 但无法弄清楚 老师只告诉我们 谷歌一下 所以这也没有帮助 基本上 我们正在开发一个基本的管理应用程序来跟踪人们及其家人 人们
  • 将代表扩展到矩阵?

    如果你打电话rep在矩阵上 它重复其元素而不是整个矩阵 传统的修复方法是调用rep list theMatrix 我想延长rep以便它自动执行此操作 我尝试使用 rep matrix lt function x rep list x 这确实
  • 如何实现再次播放功能?

    我希望在游戏结束时得到提示 如果我还想再玩一次的话 并使用 Y N 输入 退出游戏或重复游戏 我该如何以最有效的方式解决这个问题 编辑 描述资源路径位置类型 类型 Main Main java ScaredyCat src se grupp
  • Google OR-Tools:无法运行 java 示例,java.lang.UnsatisfiedLinkError:java.library.path 中没有 jniortools

    我是java新手 我想尝试google or tools来解决车辆路由问题 只是尝试运行 java 示例here https developers google com optimization introduction run progr
  • 仅在java中使用数组计算50的阶乘

    我是java的初学者 我有一个作业要编写一个完整的程序 使用数组计算 50 的阶乘 我无法使用像 biginteger 这样的任何方法 我只能使用数组 因为我的教授希望我们理解背后的逻辑 我猜 然而 他并没有真正教我们数组的细节 所以我在这
  • 如何使用自定义转换器访问 jOOQ 生成的例程字段作为值?

    我在访问生成例程的字段时遇到问题PL pgSQL 用户定义函数 返回JSON 数据类型结果 已经提到this https stackoverflow com q 62535195 6805866问题 这是我的结果get all orders
  • 当我必须在 Netty4 编码器中调用 ByteBuf.retain() 时?

    我正在编写一个以 NUL 终止 JSON 消息的编码器 以便在消息碎片的情况下可以对其进行解码 我找到了这个样本 gt click https github com netty netty blob master codec src mai
  • 如何在 SpringDoc OpenAPI 3 中引用文件?

    我有 Spring Boot 项目 我想在其中记录我的 API 这里是正在处理的 Web 服务的示例 ApiResponses value ApiResponse responseCode 200 content Content media

随机推荐

  • 在表单之间传递数据

    我有两种形式 第一的 Form1有一个组框 一些标签和一个列表框 我按下一个按钮 然后新的Form2打开并包含一些文本 我想将文本传输到Form2到列表框中Form1 到目前为止 我所做的是将列表框的修饰符设置为public然后将此代码放入
  • 如何从视图访问 django 模型属性?

    我有一个 Django 模型 class DebtRequest models Model from user models ForeignKey User related name debt requests from user to u
  • 从资源文件夹或SD卡访问文件有什么区别

    我正在开发一个应用程序 我必须使用三种不同大小的文件 1mb 5mb 15mb 我搜索了一下 然后知道我们可以将这些视频保存在资产文件夹中并可以使用这些视频 其次 我了解到我们可以将这些视频保存在资产文件夹中 并且安装时我们可以将所有视频移
  • Android 将 ParseObject 发送到另一个 Activity

    我有一个 ParseObject 我想发送到另一个活动 public class HWMMatch extends ParseObject implements Serializable public HWMMatch public Par
  • 查找数组中是否缺少元素的复杂性

    我正在尝试编写一个函数 用 C 语言 来检查数组是否包含所有元素 0 和 size 1 之间 例如 如果数组的大小为 3 则它应该具有 0 1 2 以任何顺序 问题是 在没有额外数组的情况下执行此操作的最有效的复杂性是多少 我的尝试的复杂性
  • 与 char *、unsigned char * 和signed char * 别名

    A char 和合格的变体 可以为任何东西起别名 是signed char and unsigned char 及其合格的变体 不受此限制 换句话说 我了解到申请是个好主意restrict to char 函数参数 如果我不希望它们为其他类
  • GWT - 构造 Java AST 时出错

    编译过程中可能是什么原因导致此错误 我已经从这个原型生成了项目https github com ArcBees Arcbees Archetypes https github com ArcBees Arcbees Archetypes我只
  • OpenGL ES 和 OpenGL 兼容着色器

    我想要 OpenGL ES 和 OpenGL Windows 具有相同的着色器源 为此 我想定义自定义数据类型并仅使用 OpenGL ES 函数 一种方法是定义 define highp define mediump define lowp
  • JavaFX 8 计算“textarea”中的行数

    我们正在尝试计算 TextArea 中的行数以下是 TextArea 属性 PrefWidth 600 和 PrefHeight 620 以及 MaxHeight 620文本换行设置为 true 我们将 JavaFX 8 与场景生成器一起使
  • 小时显示 hourSegments 角度日历

    在我的日历中 我需要显示一天和一周的时间 如下所示 09 00 09 15 09 20 我把包升级到最新了 angular calendar version 0 26 1 现在下面的代码出现错误 我无法再像以前一样显示时间 模块 ts cl
  • 复制并粘贴值而不是公式

    第一次编写宏 我必须仅将单元格值复制到另一个单元格值 并且我让它工作 但是 我不确定如何在不指定范围的情况下复制整个列 因为范围每次可能不同 在这里 我尝试使用一个有效的范围 但我希望它检查该列的单元格值 直到找到值复制 粘贴到另一列 这是
  • Vue.js / webpack 没有创建构建文件?

    这可能是一个愚蠢的问题 但到底是什么 我正在使用 vue cliwebpack simple模板 在该项目的 webpack 配置中我发现以下内容 output path path resolve dirname dist publicPa
  • 使“枚举时修改”集合成为线程安全的

    我想创建一个线程安全的集合 可以在枚举时进行修改 例子ActionSet类商店Action处理程序 它有Add方法将新的处理程序添加到列表中 并且Invoke枚举并调用所有收集的操作处理程序的方法 预期的工作场景包括非常频繁的枚举 并且在枚
  • Java dom4j org/jaxen/NamespaceContext 异常

    我已经下载了并将其添加到java的构建路径中 我也熟悉java lang NoClassDefFoundError org saxpath SAXPathException https stackoverflow com questions
  • 程序如何覆盖之前的输出行?

    程序如vim top or alsamixer输出多行文本并以某种方式操作已写入的文本行 我知道写 r字符到 stdout 这会将光标返回到行的开头 允许覆盖当前行 但不能覆盖之前的任何行 这些程序正在做什么才能拥有这些更高级的用户界面以及
  • 如何通过 DialogFragment 使用 startActivityForResult() ?

    我的应用程序需要添加用户名才能正常运行 mainActivity 在顶部显示从数据库检索的用户名 mainActivity 还有一个按钮 可通过 startActivityForResult 方法进入 addusername 活动 当用户实
  • Composer 缓存不适用于 bitbucket 管道构建

    我在我的 bitbucket 管道中得到了这个 pipelines branches develop step caches composer name unit tests Delivery image totersapp laravel
  • 为什么委托中所有方法都具有相同的名称?

    我从 Swift 开始 开发一个带有 tableView 的简单应用程序 对服务器的请求以及其他一些内容 我意识到 UITableViewDelegate 协议中的每个方法都以相同的方式命名 我猜它可能与其他协议相同 并且通过更改传递给这些
  • GCC 是否优化汇编源文件?

    我可以使用 GCC 将汇编代码文件转换为可重新分配的文件 gcc c source S o object o O2 优化选项是否有效 我可以期望 GCC 优化我的汇编代码吗 No GCC 将汇编源代码通过预处理器 然后传递到汇编器 任何时候
  • Java泛型通配符问题

    在使用 Google Guava 优秀的 Multimap 时 我遇到了一些泛型问题 我有一个这样定义的类型处理程序 public interface Handler