IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

[Generics] Pourquoi ce warning?


Sujet :

Langage Java

  1. #1
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut [Generics] Pourquoi ce warning?
    Salut,

    Je me demande pourquoi dans ce cas particulier, il y a un warning:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class GenericsTest<T> {
    	
    	public void call() {
    		method(new ArrayList<T>(), new LinkedList<T>());
    	}
    	
    	public void method(Collection<T>... col) {}
    
    }
    Ce qui est souligné provoque le warning:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Type safety : A generic array of Collection<T> is created for a varargs 
     parameter
    Quel est l'intérêt?

    Si on faisait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    method(new Collection[] { new ArrayList<T>(), new LinkedList<T>() });
    ok, mais là, avec le varargs, il ne peut pas y avoir de problème de type, vu que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    method(new ArrayList<Integer>(), new LinkedList<String>());
    par exemple provoque une erreur de compilation...


    Le "type safety" est donc garanti à la compilation, pourquoi ce warning?

  2. #2
    Membre expérimenté
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Par défaut
    Bonjour,
    je m'avance peut-être un peu, mais vu que le mécanisme des varargs est basé justement sur un type tableau, il ne peut pas combiner template et tableau. on ne voit pas le tableau, mais c'est ce qui est fait à la compilation.

    Le message d'erreur indique qu'on ne peut pas combiner varargs et templates, mais apparement ta question est plus pourquoi c'est interdit, plutôt que qu'est ce qui est interdit?

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Bonjour,
    Juste pour compléter la réponse de deltree, en principe il n'est pas permis de déclarer un array de type paramétré. Une instruction comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyClass<String>[] arr = new MyClass<String>(10);
    va générer une erreur. Cette restriction est en relation avec le mécanisme interne à la JVM, appelé erasure concernant les generics. Au runtime, il n'existe pas de type generic dans la jvm, ce qui fait qu'un type MyClass<String>[] devient un simple MyClass[] lors de l'exécution, après erasure. On peut donc le convertir en Object[]
    Mais comme on sait qu'un array se souvient de son type de composant et lance une ArrayStoreException quand on essaie de stocker un élément du mauvais type. Permettre des array de type generics passerait la compilation, mais pourrait créer des erreurs à l'exécution, ce qui enlèverait la sécurité apportée par les generics...
    Voilà, c'est vrai que ça se complique un peu, les generics, quand on essaie d'aller plus loin.

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    En effet les tableaux et les Generics se marient très mal, et comme les varargs utilisent des tableaux en internes, le compilateur te signale un problème potentiel...

    J'ai fait une Question/Réponse pour la FAQ concernant ce problème. Elle n'est pas encore intégrée mais tu peux la lire ici (troisième Q/R) : http://www.developpez.net/forums/sho...=2#post2342471

    Sinon tu trouveras plus de détail sur ce problème en particulier sur cette page (en anglais) : Why does the compiler sometimes issue an unchecked warning when I invoke a "varargs" method?

    a++

  5. #5
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    J'ai bien compris pourquoi on a un warning quand on crée un tableau d'objets paramétrés.

    J'ai bien compris aussi que quand on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void method(List<T>... lists) {}
    lists est de type List<T>[], et que le compilateur transforme les varargs en un tableau dont le type des generics est perdu.

    Mais... dans le cas des varargs, le compilateur PEUT faire les vérifications (et les fait) et assurer qu'il n'y aura pas d'erreur à l'exécution, contrairement à la manipulation de simples tableaux.
    Pour preuve:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class GenericsTest<T> {
     
    	public void call() {
    		// On ne type pas génériquement le new List (car ça n'est pas possible)
    		// Cet appel compile.
    		method(new List[] { new ArrayList<String>(), new LinkedList<Integer>() });
     
    		// On tente de mettre la même chose directement en varargs, ça ne
    		// compile pas
    		// car le compilateur fait la vérification du type safe
    		// il n'est donc en aucun cas possible d'avoir un mauvais type à
    		// l'exécution, d'où l'inutilité du warning
    		method(new ArrayList<String>(), new LinkedList<Integer>());
    	}
     
    	public void method(Collection<T>... col) {
     
    	}
     
    }

    Donc même si les varargs c'est converti en tableau, le compilateur pourrait "faire un cas particulier" pour éviter un warning inutile.

    Non?

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ®om
    Donc même si les varargs c'est converti en tableau, le compilateur pourrait "faire un cas particulier" pour éviter un warning inutile.
    Non car le problème ne vient pas de l'appel du vararg mais de la manière dont il sera utiliser dans la méthode. La méthode n'est pas sûr et le warning est logique en quelque sorte (selon la logique des Generics qui préviennent de tout problème probable).

    Le compilateur pourrait bien vérifier le code de la méthode pour vérifier s'il est sûr ou pas, mais ce n'est pas vraiment le rôle d'un compilateur mais plutôt d'un vérificateur de code...

    a++

  7. #7
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par adiGuba
    Non car le problème ne vient pas de l'appel du vararg mais de la manière dont il sera utiliser dans la méthode. La méthode n'est pas sûr et le warning est logique en quelque sorte (selon la logique des Generics qui préviennent de tout problème probable).

    Le compilateur pourrait bien vérifier le code de la méthode pour vérifier s'il est sûr ou pas, mais ce n'est pas vraiment le rôle d'un compilateur mais plutôt d'un vérificateur de code...

    a++
    Non mais je suis d'accord qu'il doit y avoir un warning dans la méthode, pour faire simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @SuppressWarnings("unchecked")
    void method(Collection<T>... col) {...}
    Mais une fois que ce warning est traité, il ne devrait pas y en avoir à l'appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    method(new ArrayList<T>(), new LinkedList<T>());
    ...

  8. #8
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Non, vous n'êtes pas d'accord?

Discussions similaires

  1. Warning "ArrayList is a raw type. References to generic type ArrayList<E>
    Par sandrine49 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 10/08/2008, 10h48
  2. Réponses: 2
    Dernier message: 25/04/2008, 10h43
  3. Warnings avec des generic
    Par lvr dans le forum Général Java
    Réponses: 2
    Dernier message: 22/04/2008, 12h04
  4. (Generics) Encore ce warning..
    Par utoria dans le forum Langage
    Réponses: 3
    Dernier message: 13/05/2007, 15h08
  5. "warning" dans eclipse (utiliser les Generic)
    Par Isher dans le forum Eclipse Java
    Réponses: 15
    Dernier message: 19/10/2005, 12h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo