Reputation: 2567
I want to write a function, which needs to use a the class representation of a class declaration like MyClass::class.java
.
I have a base class ActivityStarter
which I use as a base for companion objects in activities.
// declarations
open class ActivityCompanion<T: AppCompatActivity>(val activityClass : Class<T>) {
fun startActivity(context: Context) {
context.startActivity(Intent(context, activityClass))
}
}
class MyActivity : AppCompatActivity() {
companion object : ActivityStarter<MyActivity>(MyActivity::class:java)
...
}
// call
MyActivity.startActivity(this)
In the declaration, and the inheritence of the companion object, the class is basically passed twice. Once as type parameter and once as normal parameter. (ActivityStarter<MyActivity>(MyActivity::class:java)
).
The parameter activityClass
is necessary, because I cant use T::class.java
. "Cannot use T as reified type parameter. Use class instead".
I have used to just pass the parameter in the function call:
// declarations
open class ActivityStarter {
inline fun <reified T : AppCompatActivity>startActivity(context: Context) {
context.startActivity(Intent(context, T::class.java))
}
}
class MyActivity : AppCompatActivity() {
companion object : ActivityStarter()
...
}
// call
MyActivity.startActivity<MyActivity>(this)
This removes the redundancy from the companion object declaration but puts it into the call and basically makes the type parameter in the class useless.
Is there a way to make the type parameter used in the class declaration reified
, so that I can have an implementation like this?:
// declarations
open class ActivityCompanion<reified T: AppCompatActivity>() {
fun startActivity(context: Context) {
context.startActivity(Intent(context, T::class.java))
}
}
class MyActivity : AppCompatActivity() {
companion object : ActivityStarter<MyActivity>()
...
}
// call
MyActivity.startActivity(this)
Or another way to resctict the activityClass parameter so that I can have something like this:
// declarations
open class ActivityStarter(private val activityClass : Class<T : AppCompatActivity>) {
inline fun startActivity(context: Context) {
context.startActivity(Intent(context, activityClass))
}
}
class MyActivity : AppCompatActivity() {
companion object : ActivityStarter(MyActivity::class.java)
...
}
// call
MyActivity.startActivity(this)
Upvotes: 0
Views: 277
Reputation: 170919
Is there a way to make the type parameter used in the class declaration reified
No. But what if you make startActivity
not a member of ActivityCompanion
, but an extension function so it can have reified type parameters?
class ActivityCompanion<T: AppCompatActivity>()
fun <reified T: AppCompatActivity> ActivityCompanion<T>.startActivity(context: Context) {
context.startActivity(Intent(context, T::class.java))
}
class MyActivity : AppCompatActivity() {
companion object : ActivityStarter<MyActivity>()
...
}
MyActivity.startActivity(this)
Or another way to resctict the activityClass parameter so that I can have something like this:
If I understood correctly and you want ActivityStarter
to accept any subclass of AppCompatActivity
without having a type parameter itself, you can write it as
open class ActivityStarter(protected val activityClass: Class<out AppCompatActivity>) { ... }
See official documentation or What is out keyword in kotlin for the meaning of out
.
Upvotes: 1