Kotlin reified type function as function extension - Callable from Java?

2.4k views Asked by At

I'm trying to use a function with reified type as extension function but I don't think that it's possible because after I checked the generated bytecode I have find that the method signature is private, any work around to make it public ?

CommonExtensions.kt

inline fun<reified T: Activity> Context.startActivity() {
    val intent = Intent(this, T:: class.java)
    startActivity(intent)
}

fun View.visible() {
    visibility = View.VISIBLE
}

Kotlin Bytecode :

private final static startActivity(Landroid/content/Context;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   ...

Client Code :

Kotlin file

override fun showMessageEmptyOfferFeeds() {
        mOfferFeedsWarning.visible() // "visible()" extension func RESOLVED
}

Java file

showProfileDetailsUi(){
   startActivity<DetailActivity>() //"startActivity()" extension func NOT RESOLVED
}
2

There are 2 answers

5
s1m0nw1 On BEST ANSWER

Yes you can use inline functions with reified types as extension functions. It's made private so that Java code can't access it (btw this is not the case for "normal" inline functions). Such an inline function can be private for Kotlin because inline functions are copied to the place where they are invoked.

An example:

inline fun <reified T : Activity> Activity.startActivity() {
    startActivity(Intent(this, T::class.java))
}

//usage

startActivity<DetailActivity>()

Read more about reified in another SO question, I answered: https://stackoverflow.com/a/45952201/8073652

Once again: You cannot use inline functions with reified typed from Java.

1
Kiskae On

inline reified functions 'disppear' after compilation, because reified types don't exist on the JVM. It is a trick by the compiler.

Probably the only reason the private function is there is to cause an error if someone tries to override it during runtime, since the reified function is completely inlined and cannot be overridden.