Skip to content
Advertisement

How rewrite Java generec’s into Kotlin?

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.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement