Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
}
like image 237
Cool Avatar asked Sep 11 '17 14:09

Cool


People also ask

How do you use reified on Kotlin?

"reified" is a special type of keyword that helps Kotlin developers to access the information related to a class at runtime. "reified" can only be used with inline functions. When "reified" keyword is used, the compiler copies the function's bytecode to every section of the code where the function has been called.

Why does Kotlin use inline function?

Inline functions are useful when a function accepts another function or lambda as a parameter. You can use an inline function when you need to prevent "object creation" and have better control flow.

What is an extension function in Kotlin?

Extension functions are a cool Kotlin feature that help you develop Android apps. They provide the ability to add new functionality to classes without having to inherit from them or to use design patterns like Decorator.


2 Answers

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.

like image 122
s1m0nw1 Avatar answered Sep 25 '22 22:09

s1m0nw1


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.

like image 44
Kiskae Avatar answered Sep 22 '22 22:09

Kiskae