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

Collection et Stream Java Discussion :

Warning avec la méthode "clone" sur un "ArrayList"


Sujet :

Collection et Stream Java

  1. #1
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut Warning avec la méthode "clone" sur un "ArrayList"
    Salut!

    Pour copier le contenu d'un "ArrayList<ArrayList<Double>>", "matrice":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ArrayList<ArrayList<Double>> temp=new ArrayList<ArrayList<Double>>();
    for(int i=0;i<matrice.get(0).size();i++){
    	temp=(ArrayList<ArrayList<Double>>)(matrice.clone());//
    	for(int j=0;j<temp.size();j++){
    		temp.set(j,(ArrayList<Double>)(matrice.get(j).clone()));//
    	}
    .
    Mais les lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp=(ArrayList<ArrayList<Double>>)(matrice.clone());
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp.set(j,(ArrayList<Double>)(matrice.get(j).clone()));
    provoquent le warning:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type safety: The cast from Object to ArrayList<ArrayList<Double>> is actually checking against  the erased type ArrayList
    Pourtant c'est bien ainsi que doit être casté le retour de "clone", non?

    Merci de votre aide.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 62
    Points : 71
    Points
    71
    Par défaut
    Je pense que nous montrer comment est construite ta matrice aiderait bien (quel type, quelle archi, etc..).

    Deuxiemement, il est préférable d'utiliser une boucle "forEach" plutot qu'une boucle "for" dans ce cas :

    for (ArrayList<ArrayList<Double>> al : matrice.get(0) {
    ............
    }

    et pareil pour la seconde

  3. #3
    Membre régulier
    Avatar de osopardo
    Inscrit en
    Juillet 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Juillet 2005
    Messages : 92
    Points : 105
    Points
    105
    Par défaut
    Le transtypage et les types paramétrés ne font pas bon ménage pour le compileur, le seul moyen de se débarrasser de cet avertissement semble être la surcharge des méthodes clone pour qu'elles te retournent les types appropriés

  4. #4
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut
    Mais sinon il n'y a pas de risque de mauvais transtypage?
    Le résultat est bien celui attendu?
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Points : 234
    Points
    234
    Par défaut
    Je pense que le warning vient du fait que le compilateur ne vérifie pas le type du template s'il est surcasté en Object. Le seul risque, mis à part l'inadvertance, est que si tu distribues ta librairie, un utilisateur ne comprenne pas la logique et outrepasse la méthode clone() pour retourner un objet qui ne serait pas du type requis. Le compilateur n'y verrait rien si cet objet est surcasté en Object.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Object clone() {
       return new ArrayList<Float>();
    }
    La méthode d'osopardo est la plus fiable

  6. #6
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il serait peut-être plus simple de créer une nouvelle ArrayList tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp = new ArrayList<ArrayList<Double>>(matrice);
    a++

  7. #7
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut
    Adiguba=>C'est bon à savoir, merci.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  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
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba
    Salut,


    Il serait peut-être plus simple de créer une nouvelle ArrayList tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp = new ArrayList<ArrayList<Double>>(matrice);
    a++
    C'est ce que j'allais dire :-)

    D'ailleurs, je n'aime pas du tout le clone(), c'est stupide que cette méthode soit dans Object, elle devrait être dans l'interface Cloneable, avec un type paramétré...

    Et par rapport à ce qui a été dit plus haut, surcharger la méthode clone() ne changerait rien au problème, vu que clone() retourne un Object, même en surchargeant il faut que ça retourne un Object...

  9. #9
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ®om
    Et par rapport à ce qui a été dit plus haut, surcharger la méthode clone() ne changerait rien au problème, vu que clone() retourne un Object, même en surchargeant il faut que ça retourne un Object...
    Ce n'est pas tout à fait vrai : depuis Java 5.0 on peut modifier le type de retour d'une méthode qu'on redéfini à condition que celui-ci soit assignable avec le type original.
    Donc comme la méthode clone() retourne un Object, on peut la redéfinir afin qu'elle retourne n'importe quel autre type (sauf les primitifs bien entendu).

    Ceci fonctionne très bien (et l'annotation @Override prouve qu'on redéfinie bien la méthode) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class MaClasse implements Cloneable {
        
        @Override
        public MaClasse clone() {
            try {
                MaClasse mc = (MaClasse) super.clone();
                return mc;
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    Plus d'info dans la FAQ : Quelles sont les règles à respecter pour redéfinir/implémenter une méthode ?

    Par contre il est vrai que cela n'est pas très adapté au cas présent...
    a++

  10. #10
    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
    Points : 3 080
    Points
    3 080
    Par défaut
    Ah, génial, je n'avais jamais vu ça dans java 1.5 !

    Merci beaucoup, ça pourra être utile...

    Et sur la même page, je viens de voir qu'il était possible de faire un switch sur une enum... Il me semblait avoir déjà essayé sans succès, mais là je viens de tester, effectivement ça a l'air de marcher

    Sinon, tu ne trouves pas un peu bizarre le clone() qui est dans Object plutôt que dans Cloneable?

  11. #11
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ®om
    Sinon, tu ne trouves pas un peu bizarre le clone() qui est dans Object plutôt que dans Cloneable?
    La méthode clone() dans Object comporte tout le mécanisme de cloneage des objets, qui va s'occuper de créer une nouvelle instance (sans passer par le constructeur) et recopier tout ses attributs...

    L'interface Cloneable est une interface marqueur qui indique qu'il est possible de cloner cette classe. Si cette interface n'est pas "implémenté", alors la méthode clone() de Object renverra une CloneNotSupportedException qui fera tout échouer... Si ta classe implémente Cloneable, cette exception ne sera jamais remonté par la méthode clone() de Object (c'est pourquoi j'ai "supprimé" l'exception avec un bloc try/catch + une RuntimeException).

    Il y a un intérêt à cela : tu peux limiter l'utilisation de la méthode clone() car tu n'est pas obligé de la déclarer public (ce qui est le cas si elle vient d'une interface). Tu pourrais ainsi l'utiliser en interne dans ta classe dans d'autre méthode.


    a++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [W3C] Validation sur un lien PHP avec la méthode GET
    Par eMaylo dans le forum Balisage (X)HTML et validation W3C
    Réponses: 13
    Dernier message: 13/07/2010, 08h55
  2. [W3C] Validation sur un lien PHP avec la méthode GET
    Par Mooneer dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 08/06/2008, 23h32
  3. Problème sur Request.ServerVariables("QUERY_STRING"
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 25/03/2005, 11h47

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