Sobes.tech
Junior

Ce tipuri de generice cunoști?

sobes.tech AI

Răspuns de la AI

Invarianță, covarianță și contravarianță.

  • Invarianță: Tipul List<A> nu este un subtip de List<B> și vice versa, chiar dacă A este un subtip de B. Tipul rămâne exact.
  • Covarianță (out): Permite utilizarea subtipurilor. List<A> este un subtip de List<B> dacă A este un subtip de B. Folosit pentru parametrii de ieșire (valorile returnate).
fun foo(list: List<out Number>) {
    // Se poate citi din listă (Number, Double, Int etc.)
    val number: Number = list[0]
    // Nu se poate adăuga în listă (nu se știe ce tip de elemente se așteaptă)
    // list.add(1) // Eroare de compilare
}
  • Contravarianță (in): Permite utilizarea supertipurilor. List<B> este un subtip de List<A> dacă A este un subtip de B. Folosit pentru parametrii de intrare (argumente).
fun foo(comparable: Comparable<in String>) {
    // Se pot transmite argumente de tip String (sau supertipurile sale)
    val result = comparable.compareTo("hello")
    // Nu se pot obține rezultate de tip String (nu se știe ce tip de rezultat)
    // val str: String = comparable.compareTo("world") // Eroare de compilare
}

În Kotlin, aceste concepte sunt implementate cu ajutorul adnotărilor out și in pe parametrii de tip. În Java, se folosesc wildcards (? extends pentru covarianță și ? super pentru contravarianță).

Tip Scop Cuvânt cheie (Kotlin) Wildcard (Java) Citire permisă Scriere permisă
Invarianță Potrivire exactă a tipului Nu Nu Da Da
Covarianță Utilizarea subtipurilor (producer - "out") out ? extends T Da Nu
Contravarianță Utilizarea supertipurilor (consumer - "in") in ? super T Nu Da