What's the best way to get an instance of a generic type in Kotlin? I am hoping to find the best approximation of the following C# code:
public T GetValue<T>() where T : new() { return new T(); }
To use Java generics effectively, you must consider the following restrictions: Cannot Instantiate Generic Types with Primitive Types. Cannot Create Instances of Type Parameters.
You need to pass a KClass<out Cell> as a constructor parameter to CellList , and to invoke the constructor using reflection. You can also create a factory function with a reified type parameter to enable creating CellList instances with a somewhat cleaner syntax.
We can make generic variable using this kind of syntax: "val destinationActivity: Class<*>". Main part is "*".
EDIT: As mentioned in comments, this is probably a bad idea. Accepting a () -> T
is probably the most reasonable way of achieving this. That said, the following technique will achieve what you're looking for, if not necessarily in the most idiomatic way.
Unfortunately, you can't achieve that directly: Kotlin is hamstrung by its Java ancestry, so generics are erased at run time, meaning T is no longer available to use directly. Using reflection and inline functions, you can work around this, though:
/* 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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With