wandres.dev
Kotlin cheatsheet
⌘ REFERENCIA · 225 elementos

Cheatsheet de Kotlin

El lenguaje entero en un sitio: tipos, clases, genéricos, colecciones, corrutinas, Flow, interoperabilidad y herramientas. Busca por palabra clave o por el problema que tienes.

🧭 Tipos y expresiones 11

Congela la referencia, nunca el objeto al que apuntaval
Deduce dentro del cuerpo; la firma pública se anota a manoInferencia local
Por eso Kotlin no necesita un operador ternarioif y when devuelven valor
Cadena de condiciones cuando no hay un valor que compararwhen sin sujeto
Un tipo con un único valor, no el vacío de CUnit
El tipo del fondo: no tiene valores, marca la rama que no vuelveNothing
Su tipo es Nothing, y por eso encajan tras un elvisthrow y return son expresiones
Un Int no se cuela en un Long: la conversión se escribeSin conversión numérica implícita
downTo y step producen lo que el for recorre de verdadRangos y progresiones
El dólar interpola; las triples comillas no escapan nadaPlantillas de cadena
break y continue eligen a qué bucle apuntanEtiquetas en bucles

❓ Nulabilidad 11

Dos tipos distintos, con T como subtipo del nulableT frente a T?
Corta la cadena y devuelve null en lugar de lanzar?.
Elvis: la función total que da salida a la rama nula?:
Permite cerrar con throw o return sin romper el tipoNothing tras el elvis
Aserción: pides tú el NPE, y sale con tu número de línea!!
El compilador demuestra la no nulidad y te ahorra el castSmart cast
Un var de otro módulo o una propiedad open rompen la demostraciónEstabilidad
El tercer estado que llega de Java y no se puede escribirPlatform type
JSpecify en la fuente Java devuelve la garantía al tipoAnotaciones de nulabilidad
El tipo cuyo único valor posible es nullNothing?
Cuatro campos opcionales son dieciséis estados representablesDiseñar sin nulls

🔧 Funciones y lambdas 13

Con el igual se infiere el retorno; con llaves hay que declararloCuerpo de expresión
Una sola firma en lugar de una escalera de sobrecargasParámetros por defecto
Se evalúan en el orden en que tú los escribes, no en el de la firmaArgumentos con nombre
Un array desplegado dentro de la llamada, no pasado como unovararg y el asterisco
Un receptor, un parámetro y ningún punto ni paréntesisinfix
Reutilizan el ámbito sin ampliar la superficie públicaFunciones locales
El compilador fabrica una clase FicheroKt donde alojarlasNivel superior
(A) -> B es un tipo, y su aridad forma parte de élTipos función
Solo con un parámetro; en cuanto hay dos, ponles nombreit
El paréntesis se queda vacío y la llamada parece sintaxisLambda final fuera
En lugar de una lambda que se limita a llamar a algo que ya existe::referencia
return abandona la función envolvente, y solo puede si es inlineRetorno no local
Salir de la lambda sin tocar a quien la contienereturn@etiqueta

🧱 Clases, objetos y propiedades 14

Declara y asigna las propiedades en la misma línea de la firmaConstructor primario
El cuerpo del constructor troceado, y corre en orden textualinit
Un par de accesores; field solo existe dentro de ellosPropiedades, no campos
Sin campo de respaldo detrás: no ocupa memoriaPropiedad calculada
Heredar es una decisión que hay que declarar con openfinal por defecto
Sigue siendo sobrescribible salvo que lo cierres con finaloverride vuelve a abrir
Visible en el módulo; sale public al bytecode con el nombre decoradointernal
Sin inner no hay referencia a la instancia externanested frente a inner
Singleton del lenguaje, con la instancia creada de forma seguraobject
La ausencia de static, con un objeto real y una indirección detráscompanion object
El valor se copia en cada uso: cambiarlo obliga a recompilarconst val
Instancia nueva en cada evaluación, y captura su entornoExpresión de objeto
Una llamada que se lee como una construccióninvoke en el compañero
Retención permanente y pruebas que se contaminan entre síEstado en un object

📋 Data classes e igualdad 9

Genera equals, hashCode, toString, copy y las componentNdata
Lo declarado en el cuerpo queda fuera de equals y de copySolo el constructor primario
Copia superficial: lo anidado se sigue compartiendocopy
copy con argumentos con nombre; con estructuras anidadas, un muroActualizar sin mutar
Llama a equals con la comprobación de nulos ya incorporada==
La identidad, que es justo lo que == no compara===
Reordenar el constructor rompe a tus usuarios en silenciocomponentN
Llegó en 2.3.20 y quita el peligro de la posiciónDesestructurado por nombre
Entidades con identidad, jerarquías y APIs que no pueden dar copyCuándo no usar data

🔒 Sealed, enums e interfaces 12

Jerarquía cerrada: el compilador conoce todos los casos posiblessealed class
Cierra el conjunto sin gastar el único hueco de herenciasealed interface
El módulo y el paquete delimitan quién puede entrar en la jerarquíaDónde viven las subclases
Sobre un tipo cerrado hay que cubrirlo todo, también en sentenciawhen exhaustivo
Desde 2.3 el caso se escribe sin cualificarlo enteroResolución sensible al contexto
Cuenta los estados: cuatro banderas booleanas son dieciséisTipo suma
Sustituye a values() y no asigna un array nuevo en cada llamadaentries
Cuando cada entrada quiere sus propios datos, toca sealedEl límite del enum
Un solo método abstracto habilita pasar una lambda en su lugarfun interface
Puede llevar código; no puede llevar un solo byte de estadoInterfaz con cuerpo
Declaran la forma y dejan el almacén a quien implementePropiedades en interfaces
El problema de la expresión: eliges qué eje de extensión regalasSellar o abrir

🎁 Delegación y extensiones 15

El compilador escribe los reenvíos: decorador sin una línea por métodoby en los supertipos
Lo que llama el delegado no pasa por tus sobrescriturasEl envío que no vuelve
Tres modos de sincronización, y la excepción no se cacheaby lazy
Notifica el cambio después de haberlo aplicadoobservable
Devuelve false y la asignación no llega a ocurrirvetoable
Cada propiedad lee su clave del mapa que le pasesDelegar en un Map
Es una convención por nombre: no hace falta implementar interfazgetValue y setValue
El gancho que corre al crear el delegado, con la KProperty en la manoprovideDelegate
Promete inicializar antes de leer, y la excepción dice cuál fallólateinit
Estables en 2.4: entierran el patrón de la propiedad duplicadaExplicit backing fields
Función suelta que recibe el receptor como primer parámetroUna extensión es estática
Manda el tipo escrito, no el objeto que hay dentroResolución estática
Una extensión nunca sobrescribe lo que la clase ya tieneEl miembro siempre gana
Un accesor con otro nombre: no hay campo detrás que llenarPropiedad de extensión
La extensión puede recibir null y decidir ella qué hacerReceptor nulable

🎯 Funciones de scope 9

Receptor o argumento; devolver el objeto o el resultado de la lambdaLos dos ejes
El objeto llega como it y sale lo que calcules: transformarlet
El objeto como it y devuelve el objeto: para efectos al margenalso
El objeto como this y devuelve el resultado del bloquerun
Lo mismo que run, pero el objeto va como argumento y no como receptorwith
El objeto como this y lo devuelve: configurar antes de entregarapply
El valor si cumple, null si no: engancha con un elvistakeIf
El mismo filtro con la condición al revés, para leerlo mejortakeUnless
No es un problema técnico sino editorial: ¿se lee mejor así?El criterio

⚙️ inline, genéricos y varianza 12

Mata la instancia de la lambda, la llamada virtual y el boxingPor qué existe inline
Para el parámetro que sí necesitas guardar en algún sitionoinline
Prohíbe el retorno no local dentro de esa lambdacrossinline
El coste crece con el cuerpo y con el número de puntos de llamadaCuándo no insertar
Recupera en ejecución el argumento de tipo que la máquina había borradoreified
Sin inserción no hay sitio donde escribir el tipo concretoSolo dentro de inline
Un límite superior en la declaración, y el resto en la cláusula whereRestricciones
Solo produce: una lista de perros pasa donde piden animalesout
Solo consume, y la relación de subtipo va en sentido contrarioin
Pedir la flexibilidad firma a firma cuando la clase hace las dos cosasProyección de uso
No sé el argumento de tipo y declaro que no lo voy a necesitarProyección estrella
Desaparece el argumento, no el nombre de la clase que lo llevaBorrado de tipos

📚 Colecciones y secuencias 12

Es una vista: alguien puede tener la referencia mutableSolo lectura no es inmutable
Iterable, Collection, List, Set y Map; Set no añade ninguna firmaLa jerarquía
No promete un ArrayList: no dependas de la implementaciónlistOf
Los conjuntos y mapas de la stdlib lo conservan al iterarOrden de inserción
Cada operador materializa una colección intermedia enteramap y filter
Invierte el orden: cada elemento cruza la cadena completaasSequence
Cadena larga, colección grande o un first que corta antes del finalCuándo gana Sequence
Con semilla acepta otro tipo y la lista vacía; sin ella, lanzafold frente a reduce
Construir mutando y devolver ya la vista de solo lecturabuildList
Generador perezoso sobre una corrutina restringidasequence { yield(x) }
La convención que basta para que tu tipo entre en un foriterator()
Reservar de antemano, y vigilar las listas de primitivosCapacidad y boxing

🔣 Operadores y DSLs 12

No redefines un símbolo: implementas el nombre que eligió el lenguajeoperator
Los corchetes, con tantos índices como parámetros declaresget y set
Los paréntesis sobre algo que no es una funcióninvoke
La palabra in, y su negación sale gratiscontains
Recorrer tu propio tipo con el for sin heredar de nadaiterator
La notación compuesta puede resolverse hacia cualquiera de los dosplus frente a plusAssign
Los cuatro relacionales se traducen a esta única llamadacompareTo
Los dos puntos y su variante que excluye el extremorangeTo y rangeUntil
El tipo A.() -> B: de aquí sale todo DSL de KotlinLambda con receptor
El árbol no se enumera: se levanta de dentro hacia fueraBuilder con tipos
Cierra el ámbito para que no alcances el vocabulario de arriba@DslMarker
Hecho con estas cinco o seis piezas y con ninguna másGradle KTS

💥 Errores y Result 9

Java obligaba a declarar o capturar; Kotlin retiró la obligación enteraSin excepciones comprobadas
El código se reorganiza alrededor de la asignación, no de la mutacióntry es una expresión
Se ejecuta también cuando la excepción sigue subiendofinally
Contenedor de éxito o fallo, con letra pequeña al ponerlo en una firmaResult
Convierte cualquier lanzamiento en Result, también los que no queríasrunCatching
Si los fallos se pueden enumerar, su sitio es el tipo de retornoModelar el fallo como valor
Un caso por fallo, y el when obliga a tratarlos todosJerarquía sellada de error
La excepción ajena se convierte en valor pegada al adaptadorTraducir en la frontera
Lo que quien llama no puede hacer nada por resolverQué es excepcional

🌀 Corrutinas: suspend y contexto 22

No describe una ejecución: describe una reescritura en compilaciónsuspend
El parámetro extra que el compilador añade a la firma realContinuation
El cuerpo se parte por cada punto de suspensión y se reconstruyeLa máquina de estados
Distingue todavía no de este es el resultado en un único canalEl valor centinela
Concurrencia es estructura del programa; paralelismo es hardwareNo es un hilo
Ninguna corrutina es huérfana: alguien la espera y la cancelaCoroutineScope
La jerarquía padre e hijos implementada como máquina de estadosJob
Dispara un efecto y te devuelve el Job para gobernarlolaunch
Promete un valor, y ese valor hay que ir a buscarlo con awaitasync
Si un hijo falla, cancela a sus hermanos y propagacoroutineScope
El fallo de un hijo no arrastra a los demássupervisorScope
No detiene la corrutina: se lo pide, y hay que comprobarloCancelación cooperativa
La excepción que el sistema no trata como un errorCancellationException
Los puntos donde un bucle de cómputo se entera y se rindeensureActive e isActive
Para la limpieza que todavía necesita suspenderNonCancellable
Un conjunto inmutable indexado por tipos, no una bolsa de opcionesCoroutineContext
Paralelismo igual al número de núcleos: trabajo de procesadorDispatchers.Default
El pool para lo que va a bloquear, y no para calcularDispatchers.IO
Una vista acotada sobre el pool, sin crear hilos nuevoslimitedParallelism
Fusiona contextos y paga un punto de suspensión por el saltowithContext
En un pool por núcleos no ralentiza: te quita capacidad enteraBloquear es el pecado
El puente desde una API de llamadas de vueltasuspendCancellableCoroutine

🌊 Flow, canales y estado compartido 21

Una interfaz con un único método suspendido, y otra igual enfrenteFlow
Nada corre hasta que alguien recolecta, y nace de nuevo con cada unoFrío
Una lambda con receptor suspendida: de ahí sale emitflow { emit(x) }
No suspende y devuelve un flujo: solo envuelve la recetaOperador intermedio
El emisor suspende porque el recolector suspendeContrapresión gratis
Se emite desde la corrutina del recolector, y se comprueba en ejecuciónEl contrato de contexto
La forma legal de cambiar el contexto del tramo de arribaflowOn
Desacoplar productor y consumidor guardando o descartandobuffer y conflate
Cancela lo que estabas procesando cuando llega el siguiente valorcollectLatest
Valor siempre presente, conflación por igualdad y emisiones que nunca vesStateFlow
Repetición, capacidad extra y qué hacer cuando el búfer se llenaSharedFlow
La frontera oficial: colectar una vez y repartir a muchosshareIn y stateIn
Decide cuándo arranca la fuente compartida y cuándo se apagaSharingStarted
El último de cada uno frente a emparejar por turnoscombine frente a zip
Cancela el flujo interior en cuanto llega otro valor exteriorflatMapLatest
Cola que suspende en los dos extremos, no solo en el que se llenaChannel
Un canal con dueño: se cierra cuando su corrutina terminaproduce
Y que el fallo del productor llegue como excepción, no como silencioCerrar una sola vez
Espera por la primera de varias y descarta el resto atómicamenteselect
Exclusión mutua que suspende en vez de bloquear el hiloMutex.withLock
Un solo dueño del estado, y todo lo demás son mensajesConfinamiento

☕ Java y multiplataforma 20

Un método estático de verdad para quien te llama desde Java@JvmStatic
Renombrar la fachada del fichero o esquivar un choque de firmas@JvmName
Genera la escalera de sobrecargas que Java sí necesita@JvmOverloads
Campo desnudo: prohibido si hay accesor propio, delegado, open u override@JvmField
Declarar la excepción que Java espera ver en la firma@Throws
Utiles.kt se convierte en una clase llamada UtilesKtFachada de fichero
Nombres de Kotlin sustituidos al compilar por los de la plataformaTipos mapeados
Nada le impide a Java mutar la List que le entregasteSolo lectura desde Java
El compilador siembra guardas en el perímetro públicoComprobaciones de nulos
La identidad de la lambda convertida no está garantizadaConversión SAM
Un nombre en común emparejado en compilación con su realizaciónexpect y actual
Interfaz declarada en común e implementación inyectada por plataformaLa alternativa
Un nodo de un grafo dirigido acíclico, no una carpeta del discoSource set
No escribes una vez: compilas el mismo árbol una vez por objetivoQué comparte KMP
Backend hacia LLVM: código máquina sin máquina virtual debajoKotlin/Native
Enterró los objetos congelados y el modelo de memoria que imponíanEl recolector 2.0
Genera las declaraciones de una cabecera C, y suspende las garantíascinterop
Entrar es casi transparente; salir hacia Swift, mucho menosObjective-C y Swift
Los objetos viven en el montículo del motor, no en la memoria linealKotlin/Wasm
dynamic y external marcan dónde renuncias a la comprobación estáticaKotlin/JS

🛠️ Compilador, pruebas y herramientas 23

El frontend reescrito, y la reescritura desbloqueó todo lo demásK2
Una representación intermedia y cuatro backends colgando de ellaIR común
La compilación incremental depende de que siga vivo entre buildskotlinc y el demonio
Mirar lo que genera antes de creerse nada sobre el costejavap y descompilar
Instrucción para sustituir el envoltorio por su único campovalue class
La marca que la JVM necesita para poder aplanar la clase de valor@JvmInline
Como argumento genérico, nulable o vista a través de una interfazCuándo reaparece la caja
Depende del contexto sintáctico exacto, no del valor que lleveBoxing de Int
La máquina puede borrar en ejecución la asignación que tú temíasEscape analysis
Un arnés que reconstruya la historia de ejecución, o no estás midiendoMedir de verdad
Lee símbolos y añade ficheros nuevos, sin los stubs que costaba kaptKSP
No añade fuentes: reescribe la representación intermedia existentePlugin de compilador
Una fachada de anotaciones redirigida al runner de cada objetivokotlin.test
Reloj virtual: la espera se salta y el orden se respetarunTest
Encola y no ejecuta nada hasta que tú se lo pidasStandardTestDispatcher
Los mocks chocan con ellas; el fake escrito a mano noClases finales
Nada público por accidente y ningún tipo de retorno inferidoexplicit API mode
Que siga compilando no significa que siga enlazandoFuente frente a binaria
Materializar la ABI en un fichero y revisar su diff en CIVolcar la superficie
El tercer estado entre lo estable y lo privado@RequiresOptIn
La sustitución que el IDE aplica por el usuario@Deprecated con ReplaceWith
Devuelve hechos al análisis de flujo, y nadie los verifica por ticontract
Detrás de cada palabra clave hay un documento y una discusión públicaKEEP