Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is this cast in my generic Kotlin function unchecked?

Take a look at this MVCE:

abstract class Bar

class BarHolder(val barFunctor : Bar.()-> Unit)

fun <T : Bar>foo(bar: T.() -> Unit) {
    val activeRequest = BarHolder(bar as (Bar.() -> Unit))
}

The cast bar as (Bar.() -> Unit) is marked as unchecked. But I can’t think of a scenario where the cast fails at runtime, since T is always a subclass of Bar, isn’t it?

I know I can ignore it by adding @Suppress("UNCHECKED_CAST") but this seems bad practice to me. So what is the right way to avoid the unsafe cast?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

For more context, the intended use case looks similar to this:

class LongBar : Bar()
    val length = 69

fun foobar(){
    foo<LongBar>(){
        println(length)
    }
}

>Solution :

Your code is not type-safe and Kotlin is correct it should not be allowed.

The problem is that you may have a consumer of a very specific type of Bar, for example Bar1 and then you cast it to consumer of any Bar objects. What if you then use this consumer of Bar1 and pass a Bar2 object to it?

fun main() {
    val bar1Consumer: Bar1.() -> Unit = { toString() }
    val holder = foo(bar1Consumer)
    holder.barFunctor.invoke(Bar2()) // ClassCastException
}

fun <T : Bar>foo(bar: T.() -> Unit) = BarHolder(bar as (Bar.() -> Unit))

class Bar1 : Bar()
class Bar2 : Bar()

It is hard to relate to your real example as we don’t know what exactly happens in foo(), but please note after that unchecked cast this is allowed and will throw the ClassCastException:

val activeRequest = BarHolder(bar as (Bar.() -> Unit))
activeRequest.barFunctor.invoke(IntBar())
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading