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

Java Discussion :

Comparaison de deux classes en Java


Sujet :

Java

  1. #1
    Invité
    Invité(e)
    Par défaut Comparaison de deux classes en Java
    Bonjour à tous,

    Je suis actuellement en stage et je dois réaliser un programme qui génère automatiquement des class Java à partir d'une base de données.

    J'en suis à la phase de test et je souhaiterai savoir s'il est possible de comparer deux class de même nom mais situé dans des packages différents.

    Je précise que l'ordre des membres/méthodes est différent mais le contenu lui est censé être le même.

    J'avais pensé à utiliset .getClass mais je ne sais pas du tout comment l'utiliser.

    Des idées ?

    Merci d'avance

    Yamura

  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,

    tout dépend comment est définie cette comparaison

    Je suppose que tu veux comparer le code des deux classes pour savoir si c'est le même : la méthode getClass() te donnera juste une représentation de la classe mais ne te permettra pas d'accèder à son code. Tu pourras tout au plus savoir si elles ont toutes les deux les mêmes constructeurs publiques, les mêmes méthodes publiques et les mêmes variables publiques.

    Même si tu cherches à comparer le contenu des fichier .class, tu ne peux pas être sur que les contenus soient rigoureusement identique. Je veux dire que 2 .class différents octets par octets, peuvent représenter le même code : par exemple les 2 classes suivantes (qui donne le même résultat à l'utilisation) sont elles différentes ou pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package a;
    public class A {
         private int a;
         public A(int n) {
             a=n; for( int i=1;i<n;i++) { a+=i; };
         }
         public int get() { return a; }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package b;
    public class A {
         private int x;
         public A(int n) {
             for( int j=n;j>0;j--) { x+=j; };
         }
         public int get() { return x; }
    }
    Si tu génères les classes, tu dois surement avoir leur code quelquepart... mais on voit dans l'exemple ci-dessus que la comparaison n'en sera pas forcément plus évidente...
    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 Expert Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Par défaut
    Salut,

    Quel est l’intérêt d’avoir 2 classes identique dans ton projet ?

    Sinon tu peux utiliser getClass().getName() qui va te retourner le nom du package + le nom de ta classe ("java.util.ArrayList" par exemple).

    Même si tu cherches à comparer le contenu des fichier .class, tu ne peux pas être sur que les contenus soient rigoureusement identique.
    EDIT : Je dis peut être des bêtises mais j'ai peut être une idée.

    Lors de la génération de la classe:
    1/ Si aucune classe ne porte ce nom, on crée une classe de test unitaire en même temps qui analyse la signature de toutes les méthodes et qui crée un jeu de test dessus.

    2/ Si une classe de même nom est trouvé, on applique le jeu de test dessus et on compare les résultats.

    Si les résultat sont les même, on considère alors que ce sont les même classe.

    Bien évidemment cette méthode ne fournira jamais un résultat fiable a 100% mais si le jeu de données crée lors des tests est assez robuste, ne peut peut être admettre cette égalité ?

  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
    Oui ça peut être une idée @Nico02, mais je vois déjà plein de cas qui vont faire que 2 classes seront considérées comme identique alors que non ou pas vraiment.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package a;
        public class A {
        private int r;
        public A(int n) {
           r=n;
        }
        public int get() {return r;}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package a;
        public class A {
        private int r;
        public A(int n) {
           r=n;
        }
        public int get() {
           System.out.println(r); // ou création d'un fichier, ajout de données dans une base etc...
           return r;}
    }
    évidemment si les deux classes ont été générées par le même code, on doit pouvoir admettre en déduire les tests junit qui donne l'équivalence, mais comment être sur de déterminer tous les tests nécessaires pour être sur de détecter un cas discréminant

    ou l'inverse, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package a;
        public class A {
        private int r;
        public A() {
           r=(int)(Math.random()*10);
        }
        public int get() {return r;}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package b;
        public class A {
        private int r;
        public A() {
           r=(int)(Math.random()*10);
        }
        public int get() {return r;}
    }
    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
    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
    En y réfléchissant, j'oublirais le cas général, qui me semble être assez complexe pour être sur à 100%.

    Je partirais de l'algo de génération et déterminerais des heuristiques. Les classes de test unitaire pourraient être un moyen de valider ces heuristiques, en plus de la validation de l'éxécution des méthodes. Suivant la complexité de l'algo de génération, il peut être plus ou moins simple de déterminer ces heuristiques. On peut également ajouter à la la classe de test générée des informations ( sous forme de constantes ) qui permettent de valider certaines de ces heuristiques.
    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.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Tout d'abord, merci pour vos réponses.

    Plus d'informations concernant mon problème.

    J'ai accès au deux class, la class que je suis censée imité et mon imitation. Les codes sont très très proches. Il est impossible qu'il y ai ce cas par exemple :
    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
     
    package a;
    public class A {
         private int a;
         public A(int n) {
             a=n; for( int i=1;i<n;i++) { a+=i; };
         }
         public int get() { return a; }
    }
     
    package b;
    public class A {
         private int x;
         public A(int n) {
             for( int j=n;j>0;j--) { x+=j; };
         }
         public int get() { return x; }
    }
    Par contre, l'exemple ci dessous devrait me générer une erreur a cause de l'absence du System.out.println...

    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
     
    package a;
        public class A {
        private int r;
        public A(int n) {
           r=n;
        }
        public int get() {return r;}
    }
     
    package a;
        public class A {
        private int r;
        public A(int n) {
           r=n;
        }
        public int get() {
           System.out.println(r); // ou création d'un fichier, ajout de données dans une base etc...
           return r;}
    }
    Je partirais de l'algo de génération et déterminerais des heuristiques. Les classes de test unitaire pourraient être un moyen de valider ces heuristiques, en plus de la validation de l'éxécution des méthodes. Suivant la complexité de l'algo de génération, il peut être plus ou moins simple de déterminer ces heuristiques. On peut également ajouter à la la classe de test générée des informations ( sous forme de constantes ) qui permettent de valider certaines de ces heuristiques.
    Je suis encore "débutant", qu'est-ce que des heuristiques ?

    Je pense faire un algo avec tout un tas de .getClass().getName(), .getClass().getAnnotation() etc

    Exemple avec une class,
    Voici l'original
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    package com.itnsa.assurance.beans;
     
     
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
     
    @Entity
    @org.hibernate.annotations.Entity(mutable=false, dynamicInsert=false, dynamicUpdate=true)
    @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY)
     
    @Table(name = "T_AFFFAM")
    public class T_AFFFAM implements java.io.Serializable {
     
     
     
    	static final long serialVersionUID = 3174290095368000661L;
     
    	private String	TA_CODE;
    	private String	TA_LIBELLE2;
     
    	public T_AFFFAM() {}
     
    	public T_AFFFAM(String TA_CODE) {
    		this.TA_CODE = TA_CODE;
    	}
     
    	public T_AFFFAM(String TA_CODE, String TA_LIBELLE2) {
    		this.TA_CODE = TA_CODE;
    		this.TA_LIBELLE2 = TA_LIBELLE2;
    	}
     
    	@Id
    	@Column(name = "TA_CODE", unique = true, nullable = false, length = 20)
    	public String getTA_CODE() {
    		return this.TA_CODE;
    	}
     
    	public void setTA_CODE(String TA_CODE) {
    		this.TA_CODE = TA_CODE;
    	}
     
    	@Column(name = "TA_LIBELLE2", length = 200)
    	public String getTA_LIBELLE2() {
    		return this.TA_LIBELLE2;
    	}
     
    	public void setTA_LIBELLE2(String TA_LIBELLE2) {
    		this.TA_LIBELLE2 = TA_LIBELLE2;
    	}
     
     
     
    	public boolean equals(Object o) {
    		if(!(o instanceof T_AFFFAM)) {
    			return false;
    		}
     
    		T_AFFFAM obj = (T_AFFFAM) o;
     
    		if(this == obj) {
    			return true;
    		}
     
    		org.apache.commons.lang.builder.EqualsBuilder builder = new org.apache.commons.lang.builder.EqualsBuilder();
    		builder.append(this.TA_CODE, obj.getTA_CODE());
    		builder.append(this.TA_LIBELLE2, obj.getTA_LIBELLE2());
    		return builder.isEquals();
    	}
     
     
    	public String toString() {
    		return new org.apache.commons.lang.builder.ToStringBuilder(this, org.apache.commons.lang.builder.ToStringStyle.MULTI_LINE_STYLE)
    			.append("TA_CODE", TA_CODE).append("TA_LIBELLE2", TA_LIBELLE2).toString();
    	}
     
     
    }
    Et voici la copie :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    package com.itnsa.assurance.beans;
     
     
     
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import java.sql.Blob;
    import java.sql.Clob;
     
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    import org.hibernate.annotations.GenericGenerator;
    import org.hibernate.annotations.LazyCollection;
    import org.hibernate.annotations.LazyCollectionOption;
    import org.hibernate.annotations.Parameter;
     
    @Entity
    @org.hibernate.annotations.Entity(mutable=false, dynamicInsert=false, dynamicUpdate=true)
    @org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY)
     
    @Table(name = "T_AFFFAM")
    public class T_AFFFAM implements java.io.Serializable {
     
     
     
    	static final long serialVersionUID =	1;
     
     
    	private String                                TA_CODE;
    	private String                                TA_LIBELLE2;
     
    	public T_AFFFAM() {}
     
     
    	public T_AFFFAM(String TA_LIBELLE2) {
    		this.TA_LIBELLE2 = TA_LIBELLE2;
    	}
     
     
    	@Id
    	@Column(name = "TA_CODE", unique = true, nullable = false, precision = 80, scale = 0)
    	public String getTA_CODE() {
    		return this.TA_CODE;
    	}
     
    	public void setTA_CODE(String TA_CODE) {
    		this.TA_CODE = TA_CODE;
    	}
     
    	@Column(name = "TA_LIBELLE2", length = 800)	
    	public String getTA_LIBELLE2() {
    		return this.TA_LIBELLE2;
    	}
     
    	public void setTA_LIBELLE2(String TA_LIBELLE2) {
    		this.TA_LIBELLE2 = TA_LIBELLE2;
    	}
     
     
     
    	public boolean equals(Object o) {
    		if(!(o instanceof T_AFFFAM)) {
    			return false;
    		}
     
    		T_AFFFAM obj = (T_AFFFAM) o;
     
    		if(this == obj) {
    			return true;
    		}
     
    	org.apache.commons.lang.builder.EqualsBuilder builder = new org.apache.commons.lang.builder.EqualsBuilder();
    	builder.append(this.TA_CODE, obj.getTA_CODE());
    	builder.append(this.TA_LIBELLE2, obj.getTA_LIBELLE2());
    	return builder.isEquals();
    	}
     
    	public String toString() {
    		return new org.apache.commons.lang.builder.ToStringBuilder(this, org.apache.commons.lang.builder.ToStringStyle.MULTI_LINE_STYLE)
    			.append("TA_LIBELLE2", TA_LIBELLE2).toString();
    	}
     
     
     
     
     
    }

  7. #7
    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
    Une heuristique c'est en quelque sorte une "règle" simple que tu peux tester rapidement au lieu de faire tout un algo de test super complexe (ouf pas simple d'expliquer )

    prenons un exemple : imaginons que ton algo génère 2 types de classes différentes en fonction d'une valeur lue dans la base (qui peux prendre 2 valeurs différentes donc) : si ton algo est prévu par exemple pour que ton nom de classe commence toujours par une lettre en fonction de cette valeur : ça te fait déjà une heuristique pour éviter d'avoir à tester pleins de conditions qui n'existeraient que pour l'autre classe...

    si on prend ton exemple, on voit rapidement :
    - qu'on a pas les mêmes constructeurs : donc avoir les mêmes constructeur n'est pas un critère d'égalité (si ta copie doit être considérée comme égale)
    - la méthode toString ne renvoit pas la même chose, donc les test junit vont également être une mauvaise option, pourtant on peut trouver compréhensible que dans 2 environements différents les deux toString() ont leur logique (cependant, moi, je ferai un méthode spéciale pour avoir le libellé, et je ferai que la méthode toString() qui est avant tout une méthode technique, renvoit systématiquement la même chose.
    - il y a des arguments d'annotation qui ont des valeurs différentes (length=200 et length=800) : pour ça tu peux avoir une heuristique : dans le cas ce type de méthode, on peut considérer que même si les length sont différentes, on considère le test d'égalité pour cette méthode vrai
    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.

  8. #8
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Ce qu'il faudrait faire, c'est lister les différences à prendre en compte et celles à ignorer. A te lire, on a l'impression que tu ne sais pas vraiment quelles peuvent etre les différences entre 2 classes qui doivent etre détectées comme identiques.
    Ce qui est sur, comme l'a dit joel.drigo, c'est que les classes de ton exemple (qui doivent etre considérées identiques) sont différentes (les attributs et meme les constructeurs ne sont pas les memes).
    Bref, il va falloir faire un petit cahier des charges et tu vas voir que lorsque tu l'auras fait, ca va etre beaucoup plus simple...

Discussions similaires

  1. implementer une association entre deux classes uml en java
    Par tabbabi dans le forum Persistance des données
    Réponses: 8
    Dernier message: 19/04/2011, 19h39
  2. Lier deux classes java
    Par bidulee dans le forum Struts 1
    Réponses: 4
    Dernier message: 30/04/2009, 17h03
  3. passage de valeurs entre deux classes java
    Par prugne dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 17/09/2008, 10h56
  4. Comparaison de deux projets Java
    Par msalibaba dans le forum Langage
    Réponses: 1
    Dernier message: 04/06/2008, 15h59
  5. Comparaison de deux XML Doc avec java
    Par lahiane dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 10/04/2008, 11h25

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