在Kotlin中实例化泛型类型

ikh*_*ikh 14 kotlin

在Kotlin中获取泛型类型实例的最佳方法是什么?我希望找到以下C#代码的最佳(如果不是100%完美)近似值:

public T GetValue<T>() where T : new() {
    return new T();
}
Run Code Online (Sandbox Code Playgroud)

pdp*_*dpi 12

编辑:正如评论中提到的,这可能是一个坏主意.接受a () -> T可能是实现这一目标的最合理方式.也就是说,以下技术将实现您正在寻找的东西,如果不一定是最惯用的方式.

不幸的是,你无法直接实现这一点:Kotlin因其Java系统而受到限制,因此泛型会在运行时被删除,这意味着T不再可以直接使用.使用反射和内联函数,您可以解决此问题:

/* Convenience wrapper that allows you to call getValue<Type>() instead of of getValue(Type::class) */
inline fun <reified T: Any> getValue() : T? = getValue(T::class)

/* We have no way to guarantee that an empty constructor exists, so must return T? instead of T */
fun <T: Any> getValue(clazz: KClass<T>) : T? {
    clazz.constructors.forEach { con ->
        if (con.parameters.size == 0) {
            return con.call()
        }
    }
    return null
}
Run Code Online (Sandbox Code Playgroud)

如果我们添加一些示例类,您可以看到这将在空构造函数存在时返回实例,否则返回null:

class Foo() {}
class Bar(val label: String) { constructor() : this("bar")}
class Baz(val label: String)

fun main(args: Array<String>) {
    System.out.println("Foo: ${getValue<Foo>()}") // Foo@...
    // No need to specify the type when it can be inferred
    val foo : Foo? = getValue()
    System.out.println("Foo: ${foo}") // Foo@...
    System.out.println("Bar: ${getValue<Bar>()}") // Prints Bar@...
    System.out.println("Baz: ${getValue<Baz>()}") // null
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答。看起来他们当时并不能从所有现代语言中获得最好的东西...作为C#开发人员研究Kotlin,这有点令人失望。他们应该找到某种方法在运行时中发挥作用。 (3认同)
  • 疯狂的决定是通过类型擦除在Java中实现泛型以确保向后兼容,这一决定对JVM生态系统产生了长期的负面影响。 (2认同)