Junior
Quels types de génériques connaissez-vous?
sobes.tech IA
Réponse de l'IA
Invariable, covariante et contravariante.
- Invariance: Le type
List<A>n'est pas un sous-type deList<B>et vice versa, même siAest un sous-type deB. Le type reste exact. - Covariance (out): Permet d'utiliser des sous-types.
List<A>est un sous-type deList<B>siAest un sous-type deB. Utilisé pour les paramètres de sortie (valeurs retournées).
fun foo(list: List<out Number>) {
// Peut lire du liste (Number, Double, Int, etc.)
val number: Number = list[0]
// Ne peut pas ajouter au liste (on ne sait pas quel type d'éléments attendre)
// list.add(1) // Erreur de compilation
}
- Contravariance (in): Permet d'utiliser des super-types.
List<B>est un sous-type deList<A>siAest un sous-type deB. Utilisé pour les paramètres d'entrée (arguments).
fun foo(comparable: Comparable<in String>) {
// Peut passer des arguments String (ou ses super-types)
val result = comparable.compareTo("hello")
// Ne peut pas obtenir des résultats de type String (on ne sait pas quel type de résultat)
// val str: String = comparable.compareTo("world") // Erreur de compilation
}
En Kotlin, ces concepts sont implémentés avec les annotations out et in sur les paramètres de type. En Java, on utilise des wildcards (? extends pour la covariance et ? super pour la contravariance).
| Type | Objectif | Mot-clé (Kotlin) | Wildcard (Java) | Lecture autorisée | Écriture autorisée |
|---|---|---|---|---|---|
| Invariant | Correspondance exacte de type | Non | Non | Oui | Oui |
| Covariante | Utilisation de sous-types (producteur - "out") | out |
? extends T |
Oui | Non |
| Contravariante | Utilisation de super-types (consommateur - "in") | in |
? super T |
Non | Oui |