¿Cuál es el comportamiento de Iterable # all & Why Kotlin Char :: class.java! = Char.javaClass

Estoy probando un ejemplo en kotlin, como:

fun test(){ val harfler = listOf("a","b",'c','d') println(harfler.all { it.javaClass == String::class.java || it.javaClass == Char::class.java }) } 

La list contiene Char o String pero all funciones en esta expresión devuelven false , ¿Por qué return false ?

¿Alguien puede explicarlo?

Editar para @JBNizet enter image description here

Como @JB Nizet ya te ha dicho cómo analizar el problema.

De acuerdo con los types asignados , The Kotlin Char se asignará a Java Type para decidir sobre su statement.

  • cuando se declara como un tipo no bloqueable, Char es un tipo de Java primitivo.
  • cuando declarar como un tipo de nullable Char? es un Character tipo envoltorio de Java.
  • cuando se declara como un argumento de tipo List<Char> es un tipo de envoltorio Java Character .

     val it = 'a' // v--- it should be `Any` val array: Array<Any> = arrayOf('a') // v--- char println(it.javaClass) // v--- print [java.lang.Character] println(array.map { it.javaClass }) 

Pero quiero decir que hay una diferencia entre el uso y la statement . Por ejemplo, el tipo de parámetro es un java.lang.Character , pero su javaClass es char .

 fun typeOf(it: Char?) = it?.javaClass fun test() { // v--- java.lang.Character println(::typeOf.javaMethod!!.parameterTypes[0]) // v--- but it return `char` rather than `java.lang.Character` println(typeOf('a')) } 

Y el siguiente ejemplo muestra los diferentes más, por eso declaro que el tipo de Array<Any> es Array<Any> lugar de Array<Char> en el ejemplo anterior:

 // v--- uses `java.lang.Character` instead val array: Array<Char> = arrayOf('a') // v--- java.lang.Character println(array.javaClass.componentType) // v--- [char] println(array.map { it.javaClass }) 

¿ Por qué ocurrió el extraño comportamiento en Koltin?

Esto se debe a que Kotlin Char y otras classs de envoltura representan 2 roles. uno es un tipo de primitiva de Java, otro es una class de envoltorio de Java java.lang.Character . Sin embargo, Kotlin Char está estáticamente lo que significa que no puedes cambiar su tipo en time de ejecución. y un Char debe asignarse a un char por defecto en Kotlin.

SI desea get el tipo de envoltorio cada vez, debe usar KClass.javaObjectType en KClass.javaObjectType lugar, por ejemplo:

 // v--- char println(Char::class.java) // v--- java.lang.Character println(Char::class.javaObjectType) 

La operación Iterable#all es una operación de cortocircuito, lo que significa que si algún primer elemento no cumple regresará false inmediatamente.

 inline fun <T> Iterable<T>.all(pnetworkingicate: (T) -> Boolean): Boolean { // return `false` immediately the condition didn't satisfied // v for (element in this) if (!pnetworkingicate(element)) return false return true } 

Al consultar una class de Kotlin como Char y otros. debe usar el mecanismo de verificación de tipo Kotlin en lugar del enfoque de comparación tradicional, le ayuda a evitar esa confusión. por ejemplo:

 val anything: Array<Any> = arrayOf('a') val chars: Array<Char> = arrayOf('a') println(chars.all { it is Char }) // print true println(anything.all { it is Char }) // print true 

Por lo tanto, su código puede replacese con la verificación de tipo de la siguiente manera:

 fun test() { val harfler = listOf("a", "b", 'c', 'd') // v---------------v--- use type checking here println(harfler.all { it is String || it is Char }) // print true }