Search code examples
classkotlinprimitive

kotlin's javaclass.isPrimitive fails if parameter compile-time is not actual type


The following code

fun foo(value:Double) {
    if(!value.javaClass.isPrimitive) {
        println("try again")
        return
    }
}
    println("that's nice")
}

fun main() {
    foo(0.0)
}

displays: "that's nice"

but setting value type as Any:

fun foo(value:Any) {
        if(!value.javaClass.isPrimitive) {
            println("try again")
            return
        }
        println("that's nice")
    }

fun main() {
    foo(0.0)
}

will display: "try again" even though valueruntime type is Double, link for testing : https://pl.kotl.in/HkghkAkF4

quote from https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html:

inline val T.javaClass: Class

Returns the runtime Java class of this object

which from https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isPrimitive should give me right

EDIT: removed unnecessary run{}


Solution

  • When you declare the type as Double, that's a primitive double (rather than the Double wrapper class).

    When you declare the type as Any, the method then accepts any object as a parameter, so even if you pass in a primitive double, it will be auto-boxed into a wrapper object for Double and will no longer be a primitive.

    You can see this by running this snippet on play.kotlinlang.org:

    fun main() {
        useDouble(3.0)
        useAny(3.0)
    }
    
    fun useDouble(value: Double) = println("${value.javaClass.name}")
    fun useAny(value: Any) = println("${value.javaClass.name}")
    

    Prints:

    double
    java.lang.Double