Junior
Que tipos de genéricos conhece?
sobes.tech IA
Resposta da IA
Invariantes, covariantes e contravariantes.
- Invariância: O tipo
List<A>não é um subtipo deList<B>e vice-versa, mesmo queAseja um subtipo deB. O tipo mantém-se exatamente. - Covariância (out): Permite usar subtipos.
List<A>é um subtipo deList<B>seAfor um subtipo deB. Usado para parâmetros de saída (valores devolvidos).
fun foo(list: List<out Number>) {
// Pode ler da lista (Number, Double, Int, etc.)
val number: Number = list[0]
// Não pode adicionar à lista (não se sabe que tipo de elementos se espera)
// list.add(1) // Erro de compilação
}
- Contravariância (in): Permite usar supertipos.
List<B>é um subtipo deList<A>seAfor um subtipo deB. Usado para parâmetros de entrada (argumentos).
fun foo(comparable: Comparable<in String>) {
// Pode passar argumentos String (ou seus supertipos)
val result = comparable.compareTo("hello")
// Não pode obter resultados do tipo String (não se sabe que tipo de resultado)
// val str: String = comparable.compareTo("world") // Erro de compilação
}
Em Kotlin, estes conceitos são implementados com as anotações out e in nos parâmetros de tipo. Em Java, usa-se wildcards (? extends para covariância e ? super para contravariância).
| Tipo | Propósito | Palavra-chave (Kotlin) | Wildcard (Java) | Leitura permitida | Escrita permitida |
|---|---|---|---|---|---|
| Invariante | Correspondência exata de tipo | Não | Não | Sim | Sim |
| Covariante | Uso de subtipos (produtor - "out") | out |
? extends T |
Sim | Não |
| Contravariante | Uso de supertipos (consumidor - "in") | in |
? super T |
Não | Sim |