0
votes

Comment fonctionne Java Type Erasure lorsque le paramètre Type est utilisé pour la coulée?

Je sais que les paramètres de type généralement non liés sont substitués par objet code> dans le temps de compilation. Mais comment ce morceau de code fonctionne-t-il?

void call(List list, Object o) {
    fun((Object) o);
}


0 commentaires

3 Réponses :


1
votes

Non, car les informations de type sont disponibles en Java uniquement à l'exécution, il ne compila donc rien de plus spécifique que objet . Autrement serait, si le paramètre de type t était lié, par exemple: xxx

puis le compilateur ne connaît pas le type exact au moment de la compilation, mais il fait Sachez que c'est un sous-type de numéro , donc si la méthode amusement consommé numéro comme paramètre, il serait compilé par opposition au premier exemple.

Vous pouvez trouver plus d'infos ici .


2 commentaires

Merci d'avoir répondu à ma question! Mais je ne comprends pas complètement la réponse. Tout d'abord, le code compilait-il à amusant ((numéro) o) ou juste amusant (o) dans votre exemple? Deuxièmement, je ne reçois pas le point de la déclaration sur amusant consommant numéro , je suis perdue parce que je pense que amusant ne consomme qu'un seul paramètre, alors où est le deuxième paramètre?


1. Oui, ce serait le résultat - amusant ((numéro) o) . 2. Désolé, je voulais dire juste paramètre, corrigé la réponse.



2
votes

En raison de l'effacement de type, même si votre type est A code>, il sera traité comme un objet code> dans votre exemple comme vous l'avez deviné. ce qui signifie que si vous avez passé votre deuxième élève autre que A code>, il sera réellement coulé sur objet code>.

exemple, p>

import java.util.ArrayList;
import java.util.List;

public class TypeErasure {

    static <A> void call(List<A> list, Object elem) {
        A o1 = (A) elem;
        System.out.println(o1);
    }

    static void callV2(List list, Object elem) {
        System.out.println(elem);
    }

    //bounded type
    static <A extends Number> void callV3(List<A> list, Object elem) {
        A o1 = (A) elem;
        System.out.println(o1);
    }

    public static void main(String[] args) {
        call(new ArrayList<Integer>(), "trying to cast string to Integer");
        callV2(new ArrayList<Integer>(), "trying to cast string to Integer");

        //will be casted to Number
        callV3(new ArrayList<Integer>(), 1);
        callV3(new ArrayList<Double>(), 1.5);
        callV3(new ArrayList<Long>(), 1L);

        // following will fail at runtime with ClassCastException
        /* Exception in thread "main" java.lang.ClassCastException: 
           class java.lang.String cannot be cast to class java.lang.Number 
          (java.lang.String and java.lang.Number are in 
           module java.base of loader 'bootstrap')
        */
        callV3(new ArrayList<Integer>(), "trying to cast string to Integer");
    }

}


1 commentaires

Merci! Donc, dans callv3 , a o1 = (a) elem sera compilé à numéro o1 = (numéro) elem ?



0
votes

sera-t-il compilé à

Non, aucun casting ne sera inséré si la limite est objet , car une mise en forme sur objet réussit toujours.

si la variable de type était borné, par exemple T EXTENDENS Numéro , puis une instruction CochIt serait inséré pour s'assurer que O est un numéro , équivalent à < Code> (numéro) o .

Vous remarquerez peut-être que le compilateur génère un avertissement non coché sur cette ligne. Un avertissement non coché signifie que le compilateur est incapable d'insérer un bytecode pour s'assurer que O est une instance de t , spécifiquement.


C'est Il convient également de souligner que la variable de type est redondante. Vous pouvez utiliser ce qui suit et ce sera équivalent: xxx

La distribution est inutile, car amusant doit pouvoir accepter tout Objet quand même.


0 commentaires