Maison > Java > JavaQuestions d'entretien > le corps du texte

Parlons du mécanisme générique de Java

王林
Libérer: 2021-01-27 09:59:06
avant
2124 Les gens l'ont consulté

Parlons du mécanisme générique de Java

Intervieweur : Parlez-moi du mécanisme générique de Java.

(Partage vidéo d'apprentissage : Tutoriel vidéo Java)

Réponse de la version Lite

Lors du développement de Java, en utilisant la syntaxe diamant <, Make une classe, une interface ou une méthode possède un groupe de classes qui acceptent une référence générique comme paramètre. La classe générique est finalement définie par les règles entre crochets. La classe générique est généralement représentée par une lettre majuscule, généralement la lettre T, et. est ensuite transmis par le compilateur Java Lors de la compilation, les génériques seront effacés, remplacés en fonction de la classe spécifique utilisée, et le bytecode de la classe sera généré, de sorte que les génériques soient transparents pour le Jvm.

Réponse de la version Deluxe

Les génériques ont été officiellement introduits dans JDK1.5

Contexte de Java introduisant les génériques

Les collections Java autorisent plusieurs types, par exemple,

    List list=new ArrayList();
    list.add("String");
    list.add(1024);
Copier après la connexion

C'était un usage courant avant le JDK 1.5. Même s'il est placé sous le JDK actuel, il est autorisé. Ensuite, l'utilisation de cette collection causera certains problèmes. collection sait quels types sont placés dans la collection. Les autres appelants ne peuvent pas en être sûrs. De cette façon, dans les grands projets, des problèmes peuvent facilement survenir si l'appelant transfère de force un objet dans la collection, une erreur se produit. sera signalé. Ce type d'erreur ne peut pas être trouvé dans la phase de compilation à ce moment-là, et ne peut être trouvé que pendant l'exécution. Afin de résoudre des problèmes similaires, le JDK a introduit des génériques.

Types génériques

Après l'introduction des génériques, il est possible de vérifier si le type répond aux exigences lors de la phase de compilation, éliminant ainsi dans une large mesure la conversion de type aveugle. Les génériques fonctionnent principalement dans le compilateur. Après la compilation, la JVM ne peut pas percevoir les génériques lorsqu'elle est en cours d'exécution. Les génériques sont divisés en génériques ordinaires et génériques génériques.

1. Génériques ordinaires

Comme son nom l'indique, ce type de générique prend en charge n'importe quel type lors de l'appel, mais lors de l'appel, les génériques situés à gauche et à droite du signe égal doivent être cohérent. Le diamant sur le côté droit de JDK1.7 peut être omis.

class Test<T>{...} //声明时
Test<Integer> test = new Test<Integer>(); //调用时
Test<Integer> test = new Test(); //1.7调用时
Copier après la connexion

3. Génériques délimités

<?>//无界泛型,任意类型都匹配
<T extends ClassA>//有界泛型 - 继承自某父类
<T extends InterfaceB>//有界泛型 - 实现某接口
<T extends ClassA & InterfaceB & InterfaceC ... >//有界泛型 - 多重边界
<T super ClassC>//有界泛型 - 指定类父类
Copier après la connexion

Effacement générique

Comme je viens de le mentionner, les génériques ne fonctionnent que lors de l'écriture de code et de la compilation, et Jvm charge les classes. Le runtime est invisible et transparent. car le compilateur efface les génériques lors de la compilation. Pour le dire simplement et vaguement, cela signifie : supprimez les crochets <> sur la classe ou la méthode, et suivez les règles dans les crochets. Passez à une classe spécifique, donc le Jvm. Le runtime ne sait pas qu'il y a eu des génériques dans ce code auparavant. Ceci est fait pour des raisons de compatibilité. Comme mentionné précédemment, les génériques n'ont été introduits que dans JDK1.5. De cette façon, même si des génériques sont introduits, certaines JVM n'ont pas besoin de majeures. changements, il leur suffit de changer de compilateur. Pour ce type de syntaxe que le compilateur peut percevoir, mais que la machine virtuelle ne peut pas, les gens appellent cette syntaxe sugar (suger). Après désugération, les informations sèches sont obtenues et transmises à. la machine virtuelle pour l'exécution.

(Tutoriel graphique recommandé : Tutoriel d'introduction à Java)

Mécanisme d'effacement générique

//Pair的泛型
public class Pair<T> {

    private T mFirst;
    private T mSecond;

    public T getmFirst() {
        return mFirst;
    }

    public void setmFirst(T mFirst) {
        this.mFirst = mFirst;
    }

    public T getmSecond() {
        return mSecond;
    }

    public void setmSecond(T mSecond) {
        this.mSecond = mSecond;
    }
}

//Pair的原始类型
//无论何时定义一个泛型类型,都会自动提供一个相应的 原始类型
public class Pair {

    private Object mFirst;
    private Object mSecond;

    public Object getFirst() {
        return mFirst;
    }

    public void setFirst(Object mFirst) {
        this.mFirst = mFirst;
    }

    public Object getSecond() {
        return mSecond;
    }

    public void setmSecond(Object mSecond) {
        this.mSecond = mSecond;
    }
}

//如果调用Pair<T extends String>编译擦除后得到如下=
class Pair{
    private String mFirst;
    private String mSecond;
    ...
}
Copier après la connexion

Lorsque des génériques sont utilisés comme paramètres d'entrée d'une méthode, après l'effacement , il est remplacé par la borne inférieure d'un générique générique, tel que la méthode add

public static void insertElements(List<? super A> list){
    //Add进来的都是层级“小于等于”A的,也就是下界
    list.add(new A());
    list.add(new B());
    list.add(new C());
}
Copier après la connexion

Lorsqu'un générique est utilisé comme paramètre de retour d'une méthode, il est remplacé par la borne supérieure d'un générique générique après effacement, comme la méthode get

public void processElements(List<? extends A> elements){
   //for循环挨个get list 里的数据,都当做A,也就是都当做上界
   for(A a : elements){
      System.out.println(a.getValue());
   }
}
Copier après la connexion

Peu importe combien vous parlez d'effacement de type générique, peu importe le nombre de blogs que vous lisez, la définition officielle n'est pas aussi précise que la définition officielle. Document officiel d'Oracle sur l'effacement de type

Type Erasure
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.Insert type casts if necessary to preserve type safety.Generate bridge methods to preserve polymorphism in extended generic types.Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
Copier après la connexion

Pour plus de questions d'entretien, veuillez cliquer sur : questions et réponses d'entretien Java

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!

Étiquettes associées:
source:juejin.im
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!