实例化Kotlin中的泛型类型

问题描述:

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

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

只需接收'() - > T'作为您的方法的参数。 –

+2

通常认为最好的做法是在你使用这样的代码的任何地方传递一个'() - > T'',并让调用站点处理实例化,因为你不能保证'T'将会有一个无参数的构造函数。 –

+2

@YoavSternberg你击败了我20秒:) –

编辑:正如评论所说,这可能是一个坏主意。接受() -> 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 
} 

如果再加上一些样品类,你可以看到,当一个空的构造存在,这将返回一个实例,否则返回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>()}") // [email protected] 
    // No need to specify the type when it can be inferred 
    val foo : Foo? = getValue() 
    System.out.println("Foo: ${foo}") // [email protected] 
    System.out.println("Bar: ${getValue<Bar>()}") // Prints [email protected] 
    System.out.println("Baz: ${getValue<Baz>()}") // null 
}