[Java, Kotlin] Variance de type

invariant

// Java
interface Collection<E> ... {
    void addAll(Collection<E> items);
}

void copyAll(Collection<Object> to, Collection<String> from) {
    to.addAll(from); // !!! Would not compile with the naive declaration of addAll
}

Collection<String> is not a subtype of Collection<Object>

covariant

Java: Use-site variance; Kotlin: Type projections

// Java
interface Collection<E> ... {
    void addAll(Collection<? extends E> items);
}

void copyAll(Collection<Object> to, Collection<String> from) {
    to.addAll(from); // OK!
}

assign an instance of Collection<String> to Collection<? extends Object> read E from Producer Collection<? extends E> items

// Kotlin
class Array<T>(val size: Int) {
    fun get(index: Int): T { /* ... */ }
    fun set(index: Int, value: T) { /* ... */ }
}

fun copy(from: Array<out Any>, to: Array<Any>) {
    assert(from.size == to.size)
    for (i in from.indices)
        to[i] = from[i]
}

val ints: Array<Int> = arrayOf(1, 2, 3)
val any = Array<Any>(3) { "" } 
copy(ints, any)

assign an instance of Array<Int> to Array<out Any> from: Array<out Any> only with get function

Declaration-site variance

// Kotlin
abstract class Source<out T> {
    abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
    val objects: Source<Any> = strs // This is OK, since T is an out-parameter
    // ...
}

assign an instance of Source<String> to Source<Any> objects: Source<Any> Producer out Any

contravariant

Java: Use-site variance; Kotlin: Type projections

// Java
List<Animal> animals = new ArrayList<>();
List<? super Cat> cats = animals;
cats.add(new Cat());

assign an instance of List<Animal> to List<? super Cat> write Cat to Consumer List<? super Cat> cats

// Kotlin
class Array<T>(val size: Int) {
    fun get(index: Int): T { /* ... */ }
    fun set(index: Int, value: T) { /* ... */ }
}

fun fill(dest: Array<in String>, value: String) {
    // ...
}

assign an instance of Array<CharSequence> or Array<Any> to Array<in String> dest: Array<in String> only with set function

Declaration-site variance

// Kotlin
abstract class Comparable<in T> {
    abstract fun compareTo(other: T): Int
}

fun demo(x: Comparable<Number>) {
    x.compareTo(1.0) // 1.0 has type Double, which is a subtype of Number
    // Thus, we can assign x to a variable of type Comparable<Double>
    val y: Comparable<Double> = x // OK!
}

assign an instance of Comparable<Number> to Comparable<Double> y: Comparable<Double> Consumer in Double

Declaration-site to Use-site variance

interface Comparator<in T> {
    int compare(T o1, T o2);
}

interface Foo {
    Comparator<Integer> getComparator();
}

in T -> contravariant upper Comparator<Integer> -> lower Comparator<? super Integer>

interface Comparator<T> {
    int compare(T o1, T o2);
}

interface Foo {
    Comparator<? super Integer> getComparator();
}

Use-site to Declaration-site variance

interface Baz<T, U> {
    Supplier<? extends U> baz(Consumer<? super T> consumer);
}

lower Consumer<? super T> -> upper Consumer<T> covariant -> out T

upper Supplier<? extends U> -> lower Supplier<U> contravariant -> in U

interface Baz<out T, in U> {
    Supplier<U> baz(Consumer<T> consumer);
}

Array Java covariant

Apple[] apples = new Apple[10];
Fruit[] fruits = apples;
fruits[0] = new Orange(); // throws an exception at runtime (ArrayStoreException or ArrayTypeMismatchException, respectively)
Apple apple = apples[0];

Kotlin invariant ensures compile time safety and prevents runtime errors

ref.

Recommended Posts

[Java, Kotlin] Variance de type
Conversion de type Java
[Java] Type d'énumération
Java Type facultatif
Java double type
[Java] Type de données ①-Type de base
Champ de type de classe Java
Détermination de type en Java
Étudier Java # 1 (type typique)
[Java] Conversion de type de date
[Java] Conversion de type de liste / type de tableau
Mémo d'apprentissage Java (type de données)
Essayez le type fonctionnel en Java! ①
[Java] Comparaison de la vitesse de conversion de type
[Java] Obtenir KClass en Java [Kotlin]
Etude de Java # 7 (Type de syntaxe de branche)
Java Primer Series (conversion de type)
Différences entre Java "débutant" et Kotlin
Classe Kotlin à envoyer aux développeurs Java
[Java] Type de données / produit matriciel (produit matriciel AOJ ⑧)
java (utilisez le type de classe pour le champ)
Java
Génériques Kotlin pour les développeurs Java
Java
[Java] Comparaison correcte du type String
[Java & Kotlin] Créer un RecyclerView avec plusieurs sélections
[Android] Convertir le code Java Android en Kotlin
Comment utiliser le type enum Java
[Java] Type Express Enum sans utiliser le type Enum (énumération)
[Java Siler] À propos de l'inférence de type par var
[Java] Conversion de type implicite (somme AOJ10 de nombres)
Kotlin's Class part.2 à envoyer aux développeurs Java
Relation entre les modificateurs d'accès kotlin et java
Conversion de type de données de date Java (date, calendrier, chaîne)
Concernant la comparaison d'équivalence de type de chaîne en Java
[Explication facile à comprendre! ] Conversion de type de type de référence en Java
Utiliser le type de données PostgreSQL (jsonb) à partir de Java
Injection de dépendances Spring à l'aide de Java, Kotlin
Découvrez comment Java protège l'intégrité des types
[Java ~ A propos de la définition de variable et de la conversion de type ~] Note d'étude
Convertir toutes les applications Android (Java) en Kotlin
[Note personnelle] Le type de données Java est ennuyeux
[Java] Aide-mémoire de classe de type de données / chaîne de caractères
Etude Java n ° 3 (conversion de type et exécution d'instruction)
Remarques sur les opérateurs utilisant Java ~ Type chaîne ~
[Java] Présentation du type générique de limite générique
[Pour les débutants] Différence entre Java et Kotlin
[Java] Convertit null du type Object en type String
Un ingénieur Java a comparé Swift, Kotlin et Java.
Fonctions de portée Kotlin à envoyer aux développeurs Java
Mémo de méthode de surveillance des changements de répertoire (Java, Kotlin)
[Connaissance de base de Java] À propos de la conversion de type
[Kotlin] Supprimer les fichiers en double [Java]
Conseils d'interopérabilité avec Kotlin à envoyer aux développeurs Java
Résumé Java des conversions de types fréquemment recherchées
Ce que les programmeurs Java trouvent utile avec Kotlin
Introduction à kotlin pour les développeurs iOS ④-type