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

avec Java Discussion :

Problème de cast


Sujet :

avec Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut Problème de cast
    Bonjour à tous,
    J'ai une erreur à l'exécution :

    Exception in thread "main" java.lang.ClassCastException:

    Sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      tabTrie=(Personne[])Personne.tri(tabObj,new Personne());
    Où tabTrie est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Personne[] tabTrie; //Classe Personne
    et tabObj est
    Le but du code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      tabTrie=(Personne[])Personne.tri(tabObj,new Personne());
    est d'utiliser une seule méthode ou fonction dans une Interface Comparateur :
    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
    21
    22
    23
    24
    25
     
    package Cours;
     
    //cette interface devra être implémentée par les classes 
    //pour lesquelles une comparaison des instances est envisagée 
    public interface Comparateur 
    { 
    // cette méthode pourra être appelée pour comparer les deux 
    // objets reçus en paramètre 
    // la méthode retourne un entier dont la valeur dépend 
    // des règles suivantes 
    // 1 si l’instance o1 est supérieure à o2 
    // 0 si les deux instances sont égales 
    // -1 si l’instance o1 est inférieure à o2 
    // -99 si la comparaison est impossible 
      int compare2(Object o1,Object o2); 
     
      public static final int INFERIEUR=-1; 
      public static final int EGAL=0; 
      public static final int SUPERIEUR=1; 
      public static final int ERREUR=-99; 
     
    }
    // Une telle interface qui ne contient que la définition d’une seule 
    // et unique méthode est appelée interface fonctionnelle.
    La méthode ést dans la classe Personne :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    public static Object[] tri(Object[] tablo,Comparateur trieur) 
        { 
             int i,j; 
             Object c; 
             Object[] tabloTri; 
             tabloTri=Arrays.copyOf(tablo,tablo.length); 
            for (i=0;i< tabloTri.length;i++) 
            { 
                for( j = i + 1; j<tabloTri.length;j++) 
                { 
                // utilise la fonction compare de l’objet reçu en paramètre 
                // pour comparer le contenu de deux cases du tableau 
                 if 
        (trieur.compare2(tabloTri[j],tabloTri[i])==Comparateur.INFERIEUR) 
                 { 
                      c = tabloTri[j]; 
                      tabloTri[j] = tabloTri[i]; 
                      tabloTri[i] = c; 
                 } 
                 else if 
        (trieur.compare2(tabloTri[j],tabloTri[i])==Comparateur.ERREUR) 
                 { 
                      return null; 
                 } 
                } 
            } 
             return tabloTri; 
        }
    Je dois pour utiliser cette fonction de tri fournir 2 paramètres :
    - le tableau à trier : tabObj
    - une instance de classe qui implémente l'interface Comparateur : new Personne()
    Si quelqu'un a une idée MERCI

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tabTrie=(Personne[])Personne.tri(tabObj,new Personne());
    te donne une ClassCastException parce qu'un tableau d'Object (Object[]) n'est pas castable en tableau de Personne[]. Le cast n'est pas une sorte de conversion. C'est juste un moyen de faire accepter un objet d'un certain type plus générique par une variable typée dans un type plus spécifique pour permettre de manipuler l'objet via ce type spécifique. Spécifique implique qu'il étend le type plus générique. Cela implique bien sûr que l'objet soit de cette classe spécifique.

    On peut caster un object de classe Personne, manipulé par le type Object en classe Personne qui étend Object :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Personne {
     
       public static void main(String[] args) {
     
            Personne personne = (Personne)getPersonne();
     
       }
     
       public static Object getPersonne() {
              return new Personne();
       }
     
    }
    On est obligé de caster parce que le retour de getPersonne() est de type Object. Mais on peut caster parce que l'objet retourné est de classe Personne.

    Un Object[] n'est en rien un Personne[]. Personne[] n'étend pas Object[].

    Par ailleurs pourquoi passer par le type Object, ou Object[] ? Si on doit trier des Personne, pourquoi permettre de trier autre chose ? Surtout des objets de types qui possiblement ne seraient pas comparable via la méthode compare2(Object,Object) ?
    Les types ça sert à ça : à garantir que les objets qu'on a à manipuler ont bien les caractéristiques qu'on voudrait qu'ils aient (les méthodes, les attrbuts, etc).

    Donc normalement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static Personne[] tri(Personne[] tablo,Comparateur trieur)
    Du coup plus besoin de caster.

    Ou alors, sans changer l'implémentation de tri, il faut que le tableau d'origine soit bien un tableau de Personne (un Personne[]), donc dans la méthode d'application :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object[] tabObj = new Personne[] {new Personne(),new Personne()};
     
     
    Personne[] tabTrie = (Personne[]) Personne.tri(tabObj,new Personne());
    Ici la classe du tableau est bien Personne[], donc on peut caster l'objet tabObj, en Personne[], même si on le manipule par le type Object[].

    Attention, cela fonctionne parce que tu utilises la méthode Arrays.copyOf() qui garantit que la classe du tableau copie est bien celle du tableau d'origine. Si tu implémentais la copie à la main par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object[] tabloTri =new Object[tablo.length];
    for(int k=0; k<tablo.length; k++) {
       tabloTri[k]=tablo[k];
    }
    Le retour de Object[] tri(Object[] tablo,Comparateur trieur) ne serait plus castable en Personne[], puisque de classe Object[].

    Par ailleurs, pourquoi toujours déclarer les variables en début de méthode, comme ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public static Object[] tri(Object[] tablo,Comparateur trieur) 
        { 
             int i,j; 
             Object c; 
             Object[] tabloTri; 
     
    /*... */
    }
    Tu ne fais pas du C, ou je ne sais quel langage qui impose de déclarer les variables en début de méthode/fonction...

    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
    21
    22
    23
    24
    25
    26
    27
     
    public static Object[] tri(Object[] tablo,Comparateur trieur) { 
             Object[] tabloTri = Arrays.copyOf(tablo,tablo.length); 
     
            for (int i=0;i< tabloTri.length;i++) 
            { 
                for(int j = i + 1; j<tabloTri.length;j++) 
                { 
     
                // utilise la fonction compare de l’objet reçu en paramètre 
                // pour comparer le contenu de deux cases du tableau 
                 if 
        (trieur.compare2(tabloTri[j],tabloTri[i])==Comparateur.INFERIEUR) 
                 { 
                      Object c = tabloTri[j]; 
                      tabloTri[j] = tabloTri[i]; 
                      tabloTri[i] = c; 
                 } 
                 else if 
        (trieur.compare2(tabloTri[j],tabloTri[i])==Comparateur.ERREUR) 
                 { 
                      return null; 
                 } 
                } 
            } 
             return tabloTri; 
        }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Bonjour joel.drigo et merci pour ton aide, bcp de choses dans ta réponse je vais y aller pas à pas...

    Citation Envoyé par joel.drigo Voir le message
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tabTrie=(Personne[])Personne.tri(tabObj,new Personne());
    te donne une ClassCastException parce qu'un tableau d'Object (Object[]) n'est pas castable en tableau de Personne[]. Le cast n'est pas une sorte de conversion. C'est juste un moyen de faire accepter un objet d'un certain type plus générique par une variable typée dans un type plus spécifique pour permettre de manipuler l'objet via ce type spécifique. Spécifique implique qu'il étend le type plus générique. Cela implique bien sûr que l'objet soit de cette classe spécifique.


    Tout d'abord ton premier élément de réponse qui veut dire si j'ai bien compris que la Classe "Object" n'étend pas la Classe "Personne". C bien ça ?

    Puis tu dis :

    On peut caster un object de classe Personne, manipulé par le type Object en classe Personne qui étend Object :



    public class Personne {

    public static void main(String[] args) {

    Personne personne = (Personne)getPersonne();

    }

    public static Object getPersonne() {
    return new Personne();
    }

    }

    On est obligé de caster parce que le retour de getPersonne() est de type Object. Mais on peut caster parce que l'objet retourné est de classe Personne.

    Un Object[] n'est en rien un Personne[]. Personne[] n'étend pas Object[].
    Mais là quand tu dis que Personne[] n'étend pas Object[] je ne comprends pas car pour moi toute classe étend la classe Object...
    Merci de faire une retour sur ce point

    Merci à +

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par xeron33 Voir le message
    Tout d'abord ton premier élément de réponse qui veut dire si j'ai bien compris que la Classe "Object" n'étend pas la Classe "Personne". C bien ça ?
    Oui, la classe Object n'étend pas Personne, mais c'est pas de ça que je parle.

    Citation Envoyé par xeron33 Voir le message
    Mais là quand tu dis que Personne[] n'étend pas Object[] je ne comprends pas car pour moi toute classe étend la classe Object...
    Oui, toute classe en Java étend la classe Object. Mais Object[] c'est pas Object, c'est une classe spéciale qui représente un tableau d'Object.

    Ce qu'il faut faire attention, c'est que le type d'un objet, la classe qui le définit, ce n'est pas le type d'une variable, le type par lequel on manipule l'objet référencé par la variable. Et on caste des objets (des instances de classe), pas des variables.

    On peut écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object var1 = new Personne();
    Personne var2 = (Personne)var1;
    La variable var1 est du type Object, mais l'objet référencé est du type Personne.
    On peut utiliser une variable de type Object pour référencer un objet de type Personne, parce que Personne étend Object.
    On peut caster cet objet en Personne, parce qu'il est du type Personne, pour le référencer avec une variable de type Personne.

    Si on avait une classe PersonneCelebre qui étend Personne, on pourrait écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object var1 = new PersonneCelebre();
    Personne var2 = (Personne)var1;
    Tout comme on peut référencer une instance de PersonneCelebre par une variable de type Object, parce que PersonneCelebre étend Personne qui étend Object, on peut référencer une instance de PersonneCelebre par une variable de type Personne, et on peut caster une instance de PersonneCelebre en Personne.

    Et on ne peut pas écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object var1 = new Object();
    Personne var2 = (Personne)var1; // ClassCastException parce que var1 pointe sur une instance de Object, pas sur une instance de Personne
    Avec les tableaux, c'est pareil.

    On peut écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] var1 = new Personne[10];
    Personne[] var2 = (Personne[])var1;
    On peut même écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object var1 = new Personne[10];
    Personne[] var2 = (Personne[])var1;
    Mais on ne peut pas écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] var1 = new Object[10];
    Personne[] var2 = (Personne[])var1;
    D'ailleurs on ne peut pas écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Object[] var1 = new Object[10];
    for(int i=0; i<var1.length; i++) {
        var1[i]=new Personne(); // possible parce que Personne étend Object
    }
    Personne[] var2 = (Personne[])var1; // pas possible parce que Object[], le type de ce qui est dans var1, n'étend pas Personne[],
    Alors que ça, on peut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Object[] var1 = new Object[10];
    for(int i=0; i<var1.length; i++) {
        var1[i]=new Personne(); // possible parce que Personne étend Object, on peut donc le référencer par une variable de type Object
    }
    Personne[] var2 = new Personne[var1.length];
    for(int i=0; i<var1.length; i++) {
        var2[i]=(Personne)var1[i]; // possible parce que Personne étend Object, et c'est bien Personne le type de ce qu'il y a dans var1[i]
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Par ailleurs pourquoi passer par le type Object, ou Object[] ? Si on doit trier des Personne, pourquoi permettre de trier autre chose ? Surtout des objets de types qui possiblement ne seraient pas comparable via la méthode compare2(Object,Object) ?
    Oui en effet j'ai modifié par un type Personne[] et ça fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      Personne[] tabTrie2; 
      tabTrie2=new Personne[2];
      Personne[] tabTriee; 
     
    tabTriee=(Personne[])trii(tabTrie2,      
    	    	    /*	créer une instance d’une classe interne anonyme qui implémente l’interface.
    	    		// création d’une instance de classe implémentant l’interface. Classement du plus jeune au plus vieux
    	    		// l’interface Comparateur */ 
    	    		     new Comparateur() ...
    Merci pour toutes tes explications

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

Discussions similaires

  1. [CASTS]problème de cast de Time
    Par DeVoN dans le forum Langage
    Réponses: 7
    Dernier message: 22/02/2006, 17h24
  2. [JDBC Driver][JSTL] Problème de cast de données
    Par GyLes dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 27/09/2005, 10h00
  3. problème de cast!
    Par LaseLiep dans le forum Langage
    Réponses: 3
    Dernier message: 03/06/2005, 09h30
  4. Problème de cast/serialization/externalization ?
    Par Linlin dans le forum CORBA
    Réponses: 1
    Dernier message: 06/12/2004, 16h46
  5. [C#] Problème de casting de @IDENTITY
    Par bilb0t dans le forum Accès aux données
    Réponses: 7
    Dernier message: 03/09/2004, 09h42

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