as și as? (conversie de tip) în Kotlin

as tratează o valoare ca alt tip (aruncă excepție dacă nu se potrivește); as? întoarce null în loc de excepție.

Sintaxă
val s = x as String      // ClassCastException dacă nu e String
val s = x as? String     // null dacă nu e String
import a.b.Clasa as Alias

Ce face as și as? (conversie de tip)

x as Tip spune compilatorului să trateze valoarea ca fiind de tipul Tip. Dacă la rulare valoarea nu este de acel tip, se aruncă ClassCastException. as nu convertește valori: "5" as Int nu dă numărul 5, ci o excepție. Pentru conversii folosești funcții: "5".toInt(), 5.toDouble().

x as? Tip (conversie sigură) întoarce null când tipul nu se potrivește, deci rezultatul are tipul Tip?. Se combină bine cu ?:: val n = x as? Int ?: 0.

De cele mai multe ori nu ai nevoie de as: o verificare cu is face smart cast automat. as mai apare și la importuri, pentru a da alt nume: import java.util.Date as DataJava.

Ce returnează

as: valoarea de tipul cerut. as?: valoarea sau null.

Exemple

Exemplul 1: as? cu valoare de rezervă

Setările vin ca Any. as? dă null când tipul nu se potrivește, iar ?: pune valoarea implicită.

fun main() {
    val setari: Map<String, Any> = mapOf(
        "oras" to "Constanța",
        "zileLivrare" to 3,
        "cuFactura" to "da",
    )
    val oras = setari["oras"] as? String ?: "București"
    val zile = setari["zileLivrare"] as? Int ?: 5
    val factura = setari["cuFactura"] as? Boolean ?: false
    println("Livrare în $oras, în $zile zile, factură: $factura")
}

Rezultat

Livrare în Constanța, în 3 zile, factură: false

Exemplul 2: as care eșuează

Al doilea element este Int, nu String, deci as String aruncă ClassCastException.

fun main() {
    val valori: List<Any> = listOf("Ana", 42)
    for (v in valori) {
        try {
            val text = v as String
            println("Text: ${text.uppercase()}")
        } catch (e: ClassCastException) {
            println("Nu pot trata $v ca String: ${e::class.simpleName}")
        }
    }
}

Rezultat

Text: ANA
Nu pot trata 42 ca String: ClassCastException

Exemplul 3: as nu convertește valori

Pentru a transforma un text în număr folosești toInt()/toIntOrNull(), nu as.

fun main() {
    val dinFormular: Any = "25"
    println("as? Int dă: ${dinFormular as? Int}")
    val varsta = (dinFormular as? String)?.toIntOrNull()
    println("toIntOrNull dă: $varsta, peste 5 ani: ${varsta?.plus(5)}")
    val pret: Any = 19
    val real = (pret as Int).toDouble()
    println("Preț ca Double: $real")
}

Rezultat

as? Int dă: null
toIntOrNull dă: 25, peste 5 ani: 30
Preț ca Double: 19.0

Greșeli frecvente

  • "5" as Int pentru a obține un număr: aruncă ClassCastException. Folosește "5".toInt().
  • x as String? vs x as? String: primul aruncă excepție dacă x e de alt tip (acceptă doar null în plus), al doilea întoarce null.
  • as pe o valoare care are deja tipul cerut: avertismentul No cast needed (eroare cu -Werror).

Comenzi înrudite

  • is, !is și smart cast: is verifică tipul unei valori; după verificare, compilatorul o tratează automat ca acel tip (smart cast).
  • null și null safety (?. ?: !!): null înseamnă „nicio valoare”. Kotlin separă tipurile care acceptă null (String?) și oferă ?., ?: și !! pentru ele.
  • package și import: package stabilește numele pachetului unui fișier; import aduce în fișier clase și funcții din alte pachete.
  • Generics (<T>) și where: Generics permit clase și funcții care lucrează cu orice tip (T), verificat la compilare; where adaugă mai multe restricții pe T.