I want to implement a function that optionally takes an Activity class and redirects to it. If no class is provided, a default will be used.
In Java I'd do
public void onComplete(@Nullable Class<? extends Activity> redirectTarget) {
if (redirectTarget == null) redirectTarget = DefaultActivity.class;
ContextCompat.startActivity(context, new Intent(context, redirectTarget), null);
}
Now, I tried the following in Kotlin:
fun <T : Activity> onComplete(redirectTarget: Class<in T> = DefaultActivity::class.java) {
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}
I thought in T
would accept any subclasses of T in the parameter but in the above example, I get a warning saying
Type missmatch.
Expected: Class <in T>
Found: Class<DefaultActivity>
How do I implement a function that accepts any Activity class?
This has nothing to do with variance. This is an issue with how you're trying to use generics.
Let's say you have a function:
fun <T> print(toPrint: T) = println(toPrint.toString())
You can call this function like this:
print<Int>(1)
All is good.
But let's say you want to have a default String
parameter when the user doesn't want to specify the `toPrint' argument. Following your approach, you would do:
fun <T> print(toPrint: T = "") = println(toPrint.toString())
In a world where this is legal, what would then happen if you call the function specifying the type but not the argument? E.g.:
print<Int>()
The type of the default parameter doesn't match the type at the call site.
So how to go about solving your issue?
It turns out you don't even need a generic function, as you could do:
fun onComplete(redirectTarget: Class<out Activity> = DefaultActivity::class.java) {
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}