I'm trying to build a generic repository around Corda's vault. It should look something like this:
class VaultRepository<out T : ContractState>(private val services: CordaRPCOps) {
fun getUnconsumedStateByExternalId(externalId: String): T {
return services.vaultQuery<T>(...).states.single().state.data
}
}
But I get this error:
Cannot use 'T' as reified type parameter
I could use another vaultQuery
function, which takes a Class<T>
instead as a parameter, but I need to be able to get it from VaultRepository<T>
first.
Is there a way to get T from a classes generic type parameter list?
There are no direct ways to do this in Kotlin. In order to check the generic type, we need to create an instance of the generic class<T> and then we can compare the same with our class.
By using ::class , you get an instance of KClass. It is Kotlin Reflection API, that can handle Kotlin features like properties, data classes, etc. By using ::class. java , you get an instance of Class.
Pass the class object instead and it's easy. The idea here is that since you can't extract the type parameter from the object, you have to do it the other way around: start with the class and then manipulate the object to match the type parameter.
:: is just a way to write a lambda expression basically we can use this to refer to a method i.e a member function or property for example class Person (val name: String, val age: Int) Now we can write this to access the person which has the maximium age.
My go-to solution is to add a Class<T>
parameter to the primary constructor and a constructor-like function which gets the Class
from reified T
.
class VaultRepository<out T : ContractState>(
private val services: CordaRPCOps,
private val clazz: Class<T>
) {
fun getUnconsumedStateByExternalId(externalId: String): T {
return services.vaultQuery(..., clazz).states.single().state.data
}
}
fun VaultRepository<reified T : ContractState>(services: CordaRPCOps) =
VaultRepository(services, T::class.java)
To anticipate a specific comment: some people think fun
s shouldn't look like constructors. The Kotlin team doesn't agree.
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