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

如何在Kotlin中指定递归泛型参数?

邹丰羽
2023-03-14

我只想从使用Log4j(v2.8.2)的Java移植以下代码:

ConsoleAppender appender = ConsoleAppender.newBuilder().
            withName("ConsoleAppender").build();

问题在于newBuilder()方法,该方法在log4j中定义为某种递归泛型:

@PluginBuilderFactory
public static <B extends Builder<B>> B newBuilder() {
    return new Builder<B>().asBuilder();
}

Java代码会自动推断泛型参数,而Kotlin的情况并非如此。在Kotlin中调用此方法有什么解决方案吗?

我在Kotlin尝试的代码:

val appender = ConsoleAppender.newBuilder().withName("ConsoleAppender").build()

它有以下错误:

错误:(90,48)静态编程语言:类型推断失败:没有足够的信息来推断参数B的乐趣!

当代码在粘贴时自动从Java转换时,它会设置一些存根newBuilder


共有2个答案

应翰飞
2023-03-14

我发现等待如何解决log4j2配置,请参阅示例:

// create concrete type just to call method
// however, we should not use it, because of possible runtime casting issues
private class ConsoleBuilder : ConsoleAppender.Builder<ConsoleBuilder>()

private fun createAppender(configuration: Configuration): ConsoleAppender {
    // hide our temporary class immediately, to avoid runtime type casting issue
    return (ConsoleAppender.newBuilder<ConsoleBuilder>() as ConsoleAppender.Builder<ConsoleBuilder>).apply {
        withName("MyAppender")
        setConfiguration(configuration)
    }.build()
}
曾珂
2023-03-14

Log4J似乎使用了一种构建器模式,在Kotlin中,要求每个开放的非抽象类都有两个构建器:一个泛型,可以通过子类扩展,另一个非泛型,可以实例化。

由于您可能不想修改Log4J,我会考虑使用反射:

fun main(args: Array<String>) {
    val builder = ConsoleAppender::class.java.getMethod("newBuilder").invoke(null) as ConsoleAppender.Builder<*>
    val appender = builder.withName("ConsoleAppender").build()
    println(appender.name)
}

在discuss.kotlinlang.org看到我的回答:

Builder模式中的递归泛型

 类似资料:
  • 只能在类文本的左侧使用类 是否可以像在C#中那样对泛型参数提供类约束,或者是否可以使用其他语法来获取泛型参数的类型信息?

  • 我想为我的Swagger API创建一个递归规范。这个概念似乎没有出现在Swagger文档中,所以我怀疑这是不可能的。因此,我也愿意接受任何由Swagger支持的替代解决方案。 例如,我试图创建一个类似文档的结构。每个文档都有部分,每个部分都有文本和自己的部分。我计划使用这样的APIendpoint: http://a.b.com/docs/{文档ID} http://a.b.com/docs/{

  • 问题内容: 免责声明:我没有使用Java Generics的全部经验,但是我和我的同事花了很长时间尝试破译这种结构的接口: 接口泛型使用本身就是类型参数的确切含义是什么?这是做什么的? 问题答案: 这是有意义的-Java的Enum类是类似情况的一个很好的例子: 在有关Enum的问题中,有一些启发性的答案,应该可以为您特别了解泛型的这种用法,并且比我能更好地回答。

  • 我需要能够在运行时告诉kotlin集合的泛型类型。我怎么做?

  • 我试图实现一个接受泛型参数的函数定义,只要它扩展了另一个特定的泛型类型。简言之参数A必须扩展参数B,其中A和B都是泛型的。 下面是我的示例 用法示例如下 一些封闭的班级 和函数调用 我不想在抽象类声明中定义E,因为T已经在那里定义了。 我也试着做了以下几点: 将myList定义为接受扩展T的键 将E定义为T类型(无法找到如何指定它在函数中扩展T 但它从来都不起作用。有没有办法做到这一点?我在Sta

  • 我正在初始化的代码: 如何根据 类型在我的 函数中启动 ? ps-getForObject是spring restTemplate的标准函数-http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.Str