当前位置: 首页 > 知识库问答 >
问题:

Kafka模板-使用通配符时不适用于参数

姜松
2023-03-14

我一直在建立Kafka制作服务。我用了?键值的通配符类型泛型,因此它可以是整数String等。

@Slf4j
public abstract class ProducerService<T> {

    protected KafkaClientConfigProperties properties;

    @Autowired
    protected KafkaTemplate<?, T> kafkaTemplate;

    public void send(T value, Iterable<Header> headers) {
        ProducerRecord<?, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
        this.kafkaTemplate.send(record);
    }

但是,在调用参数ProducerRecordsend方法时,我遇到了错误

方法发送(生产记录)

我也试过了

ProducerRecord<String, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);

并且有一个错误

生产记录

有人能帮我弄明白代码有什么问题吗?谢啦


共有1个答案

闻人德庸
2023-03-14

这里有各种各样的东西可以改变/修复。首先,回答你提出的问题。出现问题的原因是,您正在创建的ProducerRecord包含一个null键变量。

因为这个类是泛型的,所以期望K作为键的类型,V作为值的类型,在那里传递null意味着K的类型不可能可以推断,这也是从你是的事实中得到增强的?作为键类型,这也是不正确的。

有各种方法可以缓解这种情况。

  1. 如果您真的有兴趣发送,那么您的类也应该接受键的类型(而不是通配符)。考虑以下示例:
public abstract class ProducerService<K, T> {

    @Autowired
    protected KafkaTemplate<K, T> template;

    public void send(T value, Iterable<Header> headers) {
    ProducerRecord<K, T> record = new ProducerRecord<>("topic", null, null, null, value, headers);
    template.send(record);
    }

}
public abstract class ProducerService<T> {

    @Autowired
    protected KafkaTemplate<String, T> template;

    public void send(T value, Iterable<Header> headers) {
    template.send("topic", value);
    }

}

从上面的两个示例可以看出,键入正确的键类型而不使用通配符对您来说应该很好。最后,还有一个建议是避免类泛型化。

对于特定的对象类型,不需要有多个生产者服务的实现。您可以简单地尝试和推广您的方法,以便能够处理任何类型的值。

 类似资料:
  • 我使用的Gretty示例来自:https://github.com/gretty-gradle-plugin/gretty-sample在主build.gradle我只修改了存储库URL(使用镜像回购由于代理): 建造。格雷德尔: 您可以看到端口被指定为: httpPort=8011 在子项目部分。当我运行Gradle时 格雷德卢:农场跑步 它报告: 因此,jetty仍在尝试使用默认端口8080。

  • 考虑下面粘贴的代码。我定义了一个非常简单的类,编译器为其生成一个隐式推导指南,这样就可以在没有显式模板参数的情况下构造它。但是,模板参数推导不适用于从仅直接转发到目标类的简单别名模板构造对象: 正如您从上面的代码注释中看到的,g给了我一个关于使用别名模板而没有模板参数的错误。我希望在这样的例子中,模板参数推导会被转发。 所以,我的问题是:这是通过明示设计目前的措辞来对班级模板的论点进行演绎的建议吗

  • 问题内容: 是否可以在方法的返回参数中使用通用通配符类型,这是否可行? 换句话说,确实可以像下面这样声明一个接口: 另外,可以说通用通配符类型仅在方法的 参数声明 时才有意义吗? 问题答案: 使用通配符类型(例如在方法正式参数中)的主要好处是为用户提供了灵活性,使其可以传递任何类型的,或任何实现Collection的东西(假设collection声明为)。您通常会发现自己在形式参数中使用通配符类型

  • 由于报告缺少react脚本库,在npm init之后运行npm start无法工作。 它在我的Windows 10机器上;我尝试卸载和重新安装节点,但它没有帮助。 我只能通过键入 否则,如果我运行: 我可以看到下面粘贴的错误。 reactapptest@0.1.0启动C:(…)\reactapptest react脚本启动npm错误!文件bash npm ERR!路径bash npm ERR!代码

  • 我正在做一个小的C项目,为此我创建了一个漂亮且方便的<code>std::ostream</code>包装器,名为<code>Logger</code>。 在类内部,我定义了一个模板化的操作符: 当模板实例化为整数类型时,如或,模板就像一个符咒。因此,声明 它编译得很好。 但是,如果我将语句更改为 编译器向我喊道模板无法实例化。 来自编译器的错误消息: 问题出在哪里? 我试图替换< code >

  • 问题内容: 我了解C 中模板的方面与Java和C#中的泛型不同。C#是一种形式,Java使用类型擦除,C 使用鸭子类型,等等。C 模板可以做很多事情,而Java和C#泛型则做不到(例如,模板专业化)。但是 Java泛型可以做很多事情,而C#和C ++则做不到(例如,使泛型族的有界类型参数成为现实 ),而 C#泛型可以做的很多事情Java和C 不能做(例如运行时通用反射)。 [编辑:显然Java泛型