https://docs.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance this article (which is technically focused on C# but it’s not hard to grok) goes over what covariance and contravariance are in more detail, but the tl;dr for your code is that, by default, the type parameter for a generic type is
invariant, which means that when you’re assigning the variable or calling methods that use the generic type, you must supply exactly the type you specified — subtypes and supertypes are not allowed.
out
makes the parameter
covariant, so you can use the type you specified and subtypes of it. This helps you because now you can safely opt into treating (for example) a
KClass<PristineNodeActivity>
like a
KClass<FragmentActivity>
We use
in
and
out
because Java’s wildcard projections (e.g.
? extends FragmentActivity
) are cumbersome, and we can relate the usage of the generic type to how we plan on using it (i.e. whether or not the object will consume (in) or produce (out) the type