Kotlin中调用Log4j2 ConfigurationBuilder.newComponent()时出现类型变量B无法推断的编译错误咨询
解决Kotlin中Log4j2
newComponent() 泛型类型推断失败的问题 这问题我之前也碰到过,核心就是Kotlin和Java在泛型类型推断上的差异——Java对这种带递归约束的泛型处理更宽松,能自动根据上下文推断出正确类型,但Kotlin在这里需要我们帮它明确指定泛型参数,才能通过编译。
问题根源
newComponent()的方法签名是<B extends ComponentBuilder<B>> ComponentBuilder<B> newComponent(String pluginName);,这里的泛型B是递归约束(自身继承带有自身泛型的父类),Kotlin没办法像Java那样,通过addComponent()的参数类型反向推断出B的具体实现类,所以才会抛出“Not enough information to infer type variable B”的编译错误。
解决方案:显式指定泛型类型
你只需要明确指定newComponent()的泛型参数为Field对应的Builder实现类FieldComponentBuilder即可,修改后的代码如下:
val builder = ConfigurationBuilderFactory.newConfigurationBuilder() val graylogAppender = builder.newAppender("Graylog", "Gelf") .addAttribute("host", "tcp:localhost") .addAttribute("port", 12201) .addComponent( // 显式指定泛型参数FieldComponentBuilder builder.newComponent<FieldComponentBuilder>("Field") .addAttribute("literal", "some value") )
记得先导入对应的类:
import org.apache.logging.log4j.core.config.builder.impl.FieldComponentBuilder
另一种可选写法:通过变量类型引导推断
如果你觉得直接写泛型参数有点繁琐,也可以先把newComponent()的结果赋值给一个指定类型的变量,让Kotlin通过变量类型完成推断:
val builder = ConfigurationBuilderFactory.newConfigurationBuilder() val graylogAppender = builder.newAppender("Graylog", "Gelf") .addAttribute("host", "tcp:localhost") .addAttribute("port", 12201) // 定义变量并指定类型,引导Kotlin完成推断 val fieldBuilder: ComponentBuilder<FieldComponentBuilder> = builder.newComponent("Field") .addAttribute("literal", "some value") graylogAppender.addComponent(fieldBuilder)
两种方式都能解决编译问题,第一种写法更简洁直接。
内容的提问来源于stack exchange,提问作者DavidZi
相关产品推荐
相关产品推荐

