在Kotlin中获取泛型类型实例的最佳方式是什么?我希望找到以下C#代码的最佳近似值:

public T GetValue<T>() where T : new() {
    return new T();
}

推荐答案

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

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

/* We have no way to guarantee that an empty constructor exists, so must return T? instead of T */
inline fun <reified T : Any> getValue(): T? {
    val primaryConstructor = T::class.constructors.find { it.parameters.isEmpty() }
    return primaryConstructor?.call()
}

If we add some sample classes, you can see that this will return an instance when an empty constructor exists, or null otherwise:

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
}

Kotlin相关问答推荐

等待下一个值时暂停Kotlin Coroutine

数据源配置

CompositionLocal 究竟如何以及何时隐式设置值?

如何将jooq multiset的结果映射到Hashmap(Java Map)?

使用 LazyListScope 嵌套可组合项

kotlin 单例异常是好是坏?

是什么让 Kotlin 中的 String 类能够使用方括号?

你怎么知道什么时候需要 yield()?

使用 Kotlin 协程时 Room dao 类出错

参考 Kotlin 中的 Java 接口静态字段

是否可以在 kotlin 中嵌套数据类?

将 Firebase 数据快照反序列化为 Kotlin 数据类

Android Studio 4.0.0 Java 8 库在 D8 和 R8 构建错误中脱糖

Kotlin JVM 和 Kotlin Native 有什么区别?

Kotlin的BiMap/2-way hashmap

如何为 Java 调用者声明返回类型为void的 Kotlin Lambda?

Kotlin out-projected 类型禁止使用

lateinit 的 isInitialized 属性在伴随对象中不起作用

我应该在哪里调用 MobileAds.initialize()?

如何在 Kotlin 中将串联转换为模板