I have java class and I need to rewrite it in kotlin. But I can’t rewrite generics into it.
Java class:
public abstract class AbstractFlagFilterFactory<T extends FlagFilter> extends FilterFactory { abstract Class<T> getFilterFlagType(); abstract void processFlag(org.jooq.SelectQuery<?> query, T flag); }
My Kotlin class
abstract class AbstractFlagFilterFactory<out FlagFilter> : FilterFactory { abstract fun getFilterFlagType(): Class<out ru.vtblife.realtyobject.domain.filters.FlagFilter> abstract fun processSetFlag( query: org.jooq.SelectQuery<...(1)>, flag: Class<out ru.vtblife.realtyobject.domain.filters.FlagFilter> ) }
Sign (1) I marked the my problem area by my opinion. But maybe the problem is somewhere else.
Advertisement
Answer
Kotlin’s <out FlagFilter>
is not equivalent to Java’s <T extends FlagFilter>
. Using out
at a generic declaration site makes the type covariant. This is called declaration-site variance, which is a feature that isn’t even supported in Java.
The feature you want here is generic upper bound. The equivalent to Java’s <T extends FlagFilter>
is <T: FlagFilter>
. This makes FlagFilter the upper bound of T.
The reason this is confusing is that Java overloads the extends
word for both variance and upper bounds, and the meaning depends on the context. If you see a ? extends
or ? super
, it’s covariance or contravariance, respectively. Otherwise, extends
is for upper bound. It also doesn’t help that the Java documentation avoids the word “variance” and instead calls covariance “upper-bounded wildcard” and contravariance “lower-bounded wildcard”.
And in your function, you should use <*>
in Kotlin as the equivalent of <?>
in Java.