Maison >Java >javaDidacticiel >Pourquoi plusieurs caractères génériques sur les méthodes génériques en Java prêtent-ils à confusion ?

Pourquoi plusieurs caractères génériques sur les méthodes génériques en Java prêtent-ils à confusion ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-23 04:03:18747parcourir

Why Does Multiple Wildcards on Generic Methods in Java Lead to Confusion?

Caractères génériques multiples sur les méthodes génériques : un casse-tête du compilateur Java

Introduction

Dans les génériques Java , les caractères génériques (*) représentent des types inconnus. Lorsque plusieurs caractères génériques sont utilisés sur des méthodes génériques, cela peut entraîner une confusion et un comportement inattendu. Cet article examine la complexité de plusieurs caractères génériques et leur impact sur la sécurité des types de Java.

La confusion

Considérez le code suivant :

public class TwoListsOfUnknowns {
    static void doNothing(List<?> list1, List<?> list2) { }

    public static void main(String[] args) {
        List<String> list1 = null;
        List<Integer> list2 = null;
        doNothing(list1, list2); // compiles fine!
    }
}

Les deux caractères génériques dans doNothing semblent n'avoir aucun rapport, vous permettant de l'appeler avec un List et une liste. Cependant, l'ajout suivant à la méthode génère une erreur de compilation :

static void doSomethingIllegal(List<?> list1, List<?> list2) {
    list1.addAll(list2); // DOES NOT COMPILE!!!
}

Cela suggère que même si list1 et list2 peuvent être de types différents, ils peuvent avoir une connexion qui empêche une utilisation directe.

La confusion des caractères génériques imbriqués

Une enquête plus approfondie révèle que la confusion ne réside pas dans plusieurs caractères génériques, mais dans des caractères imbriqués. caractères génériques :

public class LOLUnknowns1 {
    static void probablyIllegal(List<List<?>> lol, List<?> list) {
        lol.add(list); // this compiles!! how come???
    }
}

Ce code se compile sans erreur, même si la liste peut être d'un type différent de celui des éléments de mdr. Cependant, il est important de noter que ce scénario soulève des questions sur la sécurité des types.

La vérité : la conversion de capture

La confusion vient d'un concept appelé conversion de capture. Il permet à certains caractères génériques de capturer des types spécifiques lorsqu'ils sont utilisés dans des méthodes génériques. C'est pourquoi la variante suivante de probablementIllegal compile :

static void probablyIllegalAgain(List<List<? extends Number>> lol, List<? extends Number> list) {
    lol.add(list); // compiles fine!!! how come???
}

Ici, le caractère générique dans mdr peut capturer un type qui étend Number, tel que List ou Liste. Cela signifie que probablementIllegalAgain peut accepter des arguments qui sont tous deux des listes de nombres.

Comprendre les caractères génériques imbriqués

La clé à retenir est que plusieurs caractères génériques eux-mêmes ne posent pas de problème. La confusion survient lorsque l'on tente d'utiliser un caractère générique imbriqué pour capturer un type qui n'est pas « compatible » en raison de la variance du type.

Dans le cas de LOLUnknowns1, le caractère générique imbriqué dans List> ne peut pas capturer un type spécifique car la capture ne serait pas sûre pour tous les types d'éléments possibles de mdr. C'est pourquoi la liste peut être de n'importe quel type, entraînant des problèmes potentiels de sécurité des types.

Conclusion

Plusieurs caractères génériques sur les méthodes génériques peuvent prêter à confusion, mais comprendre la conversion de capture et ses limites sont cruciales. Les caractères génériques imbriqués nécessitent un examen attentif pour garantir la sécurité du type. En adhérant à ces principes, vous pouvez naviguer dans les subtilités des génériques Java et écrire du code robuste.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn