Génériques Kotlin pour les développeurs Java

Certains génériques Kotlin peuvent être exprimés en Java, tandis que d'autres ne le sont pas. Commençons par ce qui peut être exprimé en Java.

Fonction générique

Déclarons une fonction générique dans Kotlin.

// Kotlin
fun <T> convertToString(arg: T) : String {
    return arg.toString()
}

Déclarez un paramètre de type entre le mot-clé fun dans une déclaration de fonction régulière et le nom de la fonction. Les fonctions équivalentes peuvent être exprimées en Java.

// Java
<T> String convertToString(T arg) {
    return arg.toString();
}

Contrainte de type

Vous pouvez contraindre les paramètres de type.

fun <T: Exception> convertToString(arg: T) : String {
    return arg.localizedMessage
}

Le paramètre de type «T» a une contrainte qui en fait une exception ou sa sous-classe. Cela peut également être exprimé en Java.

// Java
<T extends Exception> String convertToString(T arg) {
    return arg.getLocalizedMessage();
}

Classe générique

Définissons une classe générique dans Kotlin.

class Box<T>(t: T) {
    var value = t
}

Déclarez un paramètre de type entre le nom de la classe et le constructeur principal. Les classes équivalentes peuvent être représentées en Java.

class Box<T> {
    T value;
    Box(T t) {
        this.value = t;
    }
}

Contrainte de type

Vous pouvez également contraindre les paramètres de type des classes.

class Box<T: Number> (t: T) {
    var value = t
}

Le paramètre de type «T» est contraint à être Number ou sa sous-classe. Cela peut également être exprimé en Java.

static class Box<T extends Number> {
    T value;

    Box(T t) {
        this.value = t;
    }
}

Clause where

La clause where est utile lorsque vous souhaitez spécifier plusieurs contraintes de type dans une fonction ou une classe.

fun <T> doSomething(t: T) where T: Runnable, T: Cancellable {
    
}

Déclaration de variable et spécification de déplacement

Semblable au type générique de limite de Java, Kotlin a également une notation pour spécifier le déplacement lors de la déclaration de variables.

Java Kotlin
Contrainte de limite supérieure <? extends XXX> <out XXX>
Contrainte de limite inférieure <? super XXX> <in XXX>

Covariant

Le chien est un sous-type d'animal. Par conséquent, List \ crée une relation covariante afin qu'elle devienne un sous-type de List \ .

open class Animal
class Dog: Animal()

var animals: List<out Animal> = emptyList()
val dogs: List<Dog> = emptyList()

animals = dogs

Rébellion

Le chien est un sous-type d'animal. List \ crée une relation contravariante afin qu'il s'agisse d'un sous-type de List \ .

open class Animal
class Cat: Animal()

val animals: MutableList<Animal> = mutableListOf()
var cats: MutableList<in Cat> = mutableListOf()

cats = animals

Dans Kotlin, la spécification de déplacement au moment de la déclaration est appelée ** type projection **.

Déclaration de classe et spécification de déplacement

En Java, la relation entre covariant et contravariant ne peut pas être spécifiée dans la classe elle-même. Par conséquent, il est nécessaire de spécifier le déplacement à chaque fois que la déclaration de variable etc.

Kotlin, d'autre part, a un mécanisme pour spécifier le déplacement lors de la déclaration d'une classe. Il n'y a aucun risque que le déplacement soit utilisé contre l'intention du concepteur de classe ou de l'implémenteur.

//↓ Spécifier la position de sortie pour le paramètre de type
class Supplier<out T> {
    fun get(): T {
        //
    }
}

La classe Supplier est covariante par rapport au paramètre de type T.

var animalSupplier: Supplier<Animal> = Supplier()
var dogSupplier: Supplier<Dog> = Supplier()
animalSupplier = dogSupplier

Il n'est pas nécessaire de spécifier le déplacement lors de la déclaration de la variable. De même, il est possible de créer un contravariant en spécifiant la position «in».

Non-null tolérant et générique

Vous pouvez transmettre null aux fonctions et arguments génériques suivants.

fun <T> doSomething(t: T){
}

doSomething(null) // OK

Le type Kotlin qui correspond à la classe racine Java ʻObject est ʻAny. Cependant, la limite supérieure pour les paramètres de type sans contrainte est ʻAny? Au lieu de ʻAny.

Si vous souhaitez déclarer une fonction générique tolérante non nulle Spécifiez ʻAny` pour la contrainte de type.

fun <T: Any> doSomething(t: T){
}

doSomething(null) //Erreur de compilation
doSomething(1) // OK
doSomething("hoge") // OK

Projection d'étoiles

Il existe un mécanisme appelé projection en étoile qui spécifie un astérisque «*» pour le paramètre de type.

var animals: List<*> = //

La liste ci-dessus «List <*>» n'est pas égale à «List <Any?>». Il se comporte comme List <out Any?>. La projection en étoile est une syntaxe utilisée lorsque les paramètres de type ne vous intéressent pas. Il est sûr d'obtenir un élément et de le traiter comme ʻAny? `, Mais il n'est pas sûr d'ajouter un élément à une liste.

Comme indiqué ci-dessous, il se comporte comme une position «out» en raison du risque de recevoir un type inattendu.

val animals: MutableList<*> = mutableListOf<Animal>()
val animal = animals.first() // OK
animals.add(1) //Erreur de compilation
animals.add(Dog()) //Erreur de compilation

Recommended Posts

Génériques Kotlin pour les développeurs Java
Fonctionnalités du framework Spring pour les développeurs Java
Conseils d'interopérabilité avec Kotlin à envoyer aux développeurs Java
[Pour les débutants] Résumé du constructeur java
Classe Kotlin à envoyer aux développeurs Java
[Java] Génériques
Implémentation de la méthode de clonage pour Java Record
Kotlin's Class part.2 à envoyer aux développeurs Java
Introduction à kotlin pour les développeurs iOS ⑥ ー création de kotlin
Mémo pour la migration de Java vers Kotlin
Résumé des génériques Java
Pour l'apprentissage JAVA (2018-03-16-01)
[Java] Exemple de génériques
Génériques Java (Notes)
IDE 2017 pour Java
[Java] Présentation de Java
Java pour instruction
Fonctions Kotlin et lambdas à envoyer aux développeurs Java
Spécifier les options de compilation Java / Kotlin pour les applications Android
Récapitulatif des paramètres de l'environnement Java pour moi-même [mac]
Paramètres initiaux pour la réécriture de projets Java sur Kotlin
Premiers pas avec Kotlin à envoyer aux développeurs Java
Notes de pré-introduction pour les apprenants JavaScript expérimentés de Java
Une collection de questions simples pour les débutants Java
Introduction à kotlin pour les développeurs iOS ③-À propos de gradle
Introduction à kotlin pour les développeurs iOS ①-Construction de l'environnement
Introduction à kotlin pour les développeurs iOS ②-Création de projet
[Introduction à Java] Bases de l'arithmétique Java (pour les débutants)
[Java] pour instruction, while instruction
Collection expirée de java
Caractéristiques prévues de Java
[Java] Importance de serialVersionUID
Obtenir une liste d'informations MBean pour les applications Java
Veuillez noter la division (division) de java kotlin Int et Int
[Java] Package de gestion
[Pour les débutants] Comprendre rapidement les bases de Java 8 lambda
NIO.2 examen de Java
Avis sur Java Shilber
[Java] pour instruction / étendu pour instruction
Initialisation de for Essayez de changer le problème Java en TypeScript 5-4
Parcourir les objets de classe dans Kotlin (au lieu de Java class name.class)
java --Unification des commentaires
Génériques Java fréquemment utilisés
Contre-mesures pour OutOfMemoryError en java
[Java, Kotlin] Variance de type
Histoire des annotations Java
PNL pour Java (NLP4J) (2)
(Mémo) Java pour instruction
PNL pour Java (NLP4J) (1)
Introduction à Java pour les débutants Connaissance de base du langage Java ①
Liste des instructions Java fréquemment utilisées (pour les débutants et les débutants)
Examen NIO de Java
[Java] [Kotlin] Appeler valueOf et les valeurs de Enum de manière générique
[Java10] Veillez à utiliser ensemble var et génériques
[Java] Trois fonctionnalités de Java
Liens pour chaque version (version japonaise) de l'API Java SE
[Sécurité Null] Mémo de comparaison Kotlin Java Utilisation correcte de la sécurité Null
Comment exécuter l'exemple WebCamCapture de NyARToolkit pour Java
Résumé du support Java 2018
Résumé des méthodes de lecture de fichiers pour chaque format de fichier Java