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 :

Classe et serialVersionUID


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Classe et serialVersionUID
    Bonjour,

    Je quitte prochainement le Delphi pour partir sur un poste de développeur Java. Je me documente sur Java pour arriver avec un petit bagage.

    A l'époque j'avais écrit en Delphi un moyen de calculer le Lattice path avec le triangle de Pascal.
    En mathématiques, le triangle de Pascal est une présentation des coefficients binomiaux dans un triangle. Celui-ci permet de résoudre le problème du Lattice Path ou il faut calculer le nombre de chemins possible pour traverser un carré un partant du coin supérieur droit pour arriver au point en bas à gauche en se déplacent uniquement sur la droite et le bas.
    Je pense que c'est un bon exemple pour le réécrire en Java.

    Je suis arriver à ce résultat :
    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
    import java.util.ArrayList;
     
    public class Calcul {
     
    	public static void main(String[] args) {
    		System.out.print(GetResultat(20));
     
    	}
     
    	public static long GetResultat(int aValue) {
    		ArrayList<Ligne> tab = new ArrayList<Ligne>();	
    		tab.clear();
    		for(int i = 0; i <= aValue * 2; i++) {
    			Ligne ln = new Ligne();
     
    			for(int j = 0; j <= i; j++) {
    	        	// création de la cellule
    	            Cellule cel = new Cellule();
     
    	            // chaque ligne commence et termine par un 1
    	            if ((j == 0) || (j == i)) {
    	            	cel.Value = 1;
    	            } 
    	            else {
    					// la valeur de la cellule est égale à la somme sur la ligne précédente
    					// de la valeur de la cellule du même index - 1 plus la valeur de la cellule du même index
    	            	cel.Value = tab.get(tab.size() - 1).Cellules.get(j - 1).Value + 
    							    tab.get(tab.size() - 1).Cellules.get(j).Value;
    	            }
     
    	            // ajout de la cellule dans la ligne
    	            ln.Cellules.add(cel);
     
    	         } 
     
                // ajout de la ligne dans le tableau
                tab.add(ln);
    		}
     
    		return tab.get((int) (aValue * 2)).Cellules.get((int) aValue).Value;
    	}
    }
     
    class Cellule {
    	long Value;
    }
     
    class Ligne {
    	ArrayList<Cellule> Cellules = new ArrayList<Cellule>();
     
    	public String ToString() {
    		String res = "";
     
    		for(int i = 0; i <= Cellules.size() - 1; i++) {
    			res += Cellules.get(i).Value;
    		}
     
    		return res;	
    	}
    }
    Ensuite j'ai modifié légèrement pour avoir directement les classes dérivant d'une collection générique.

    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
    import java.util.ArrayList;
     
    public class Calcul {
     
    	public static void main(String[] args) {
    		System.out.print(GetResultat(2));
     
    	}
     
    	public static long GetResultat(int aValue) {
    		Tableau tab = new Tableau();	
    		tab.clear();
     
    		for(int i = 0; i <= aValue * 2; i++) {
    			Ligne ln = new Ligne();
     
    			for(int j = 0; j <= i; j++) {
    	        	// création de la cellule
    	            Cellule cel = new Cellule();
     
    	            // chaque ligne commence et termine par un 1
    	            if ((j == 0) || (j == i)) {
    	            	cel.Value = 1;
    	            } 
    	            else {
    					// la valeur de la cellule est égale à la somme sur la ligne précédente
    					// de la valeur de la cellule du même index - 1 plus la valeur de la cellule du même index
    	            	cel.Value = tab.get(tab.size() - 1).get(j - 1).Value + 
    							    tab.get(tab.size() - 1).get(j).Value;
    	            }
     
    	            // ajout de la cellule dans la ligne
    	            ln.add(cel);
     
    	         } 
     
                // ajout de la ligne dans le tableau
                tab.add(ln);
    		}
     
    		return tab.get(aValue * 2).get(aValue).Value;
    	}
    }
     
    class Cellule {
    	long Value;
    }
     
    class Ligne extends ArrayList<Cellule> {
    	public String ToString() {
    		String res = "";
     
    		for(int i = 0; i <= this.size() - 1; i++) {
    			res += this.get(i).Value;
    		}
     
    		return res;	
    	}
    }
     
     
    class Tableau extends ArrayList<Ligne> {
     
    }
    Avec cette méthode, j'ai un avertissement sur la classe Cellule et sur la classe Tableau car je n'ai pas de constante serialVersionUID.

    • Je vois pas tellement ce que c'est, est-ce que quelqu'un peut m'expliquer son intérêt ?
    • Et est-ce que mon code comprend des erreurs pour un développeur Java ?


    Dernier point, en Delphi je peux déclarer une variable Tableau comme liste de Ligne comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau = class(TObjectList<Ligne>)
    Est ce qu'il existe un équivalent en Java de ce type ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class Tableau extends ArrayList<Ligne>;
    Merci

    EDIT: Je vois des problèmes d'indentation mais sur Eclipse c'est correct..

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    Hello,

    Citation Envoyé par retwas Voir le message
    Je vois pas tellement ce que c'est, est-ce que quelqu'un peut m'expliquer son intérêt ?
    Cela a à voir avec la sérialisation Java. La sérialisation Java est un mécanisme qui permet d'enregistrer un objet Java dans un flux d'octets, et à l'inverse de pouvoir désérialiser un tel flux d'octets en le lisant et obtenir ainsi un objet Java au même contenu que celui d'origine.
    Utile par exemple pour sauvegarder ses données dans un fichier binaire, arrêter le programme, et les recharger la prochaine fois qu'on démarre le programme.

    Ici le compilateur vient te parler de la sérialisation, parce qu'on indique qu'une classe Java est compatible avec la sérialisation en lui faisant implémenter l'interface Serializable.
    ArrayList implémente cette interface, et comme tes classes étendent ArrayList, elles héritent du fait d'implémenter Serializable. Donc elles sont aussi compatibles sérialisation.

    Or il est préférable pour de telles classes, de maintenir un numéro de version de la classe, pour le cas où le programme évolue et la classe avec, et commence à contenir plus ou moins de choses qu'elles n'en avait avant. De tels changements dans cette classe va rendre la sérialisation de la classe comme elle était avant, incompatible avec comme elle est devenue ensuite, et inversement. D'où l'utilité d'un numéro de version de la classe, qu'on fait évoluer en même temps que la classe elle-même. Cela permet de détecter des incompatibilités avec les précédentes versions sérialisées, sans devoir compter sur la chance de tomber sur une contradiction implicite. (Les champs de la classe pourraient possiblement changer et devenir incompatibles, mais ressembler à ce qu'ils étaient avant et le mécanisme de sérialisation ne s'en rendra pas compte sans numéro de version.)

    Le champ static serialVersionUID est un tel numéro de version.

    Citation Envoyé par retwas Voir le message
    Et est-ce que mon code comprend des erreurs pour un développeur Java ?
    Il est préférable de ne pas étendre des classes de Collection comme ArrayList.

    Cela te sert à quoi de le faire ? Au lieu d'une nouvelle classe Ligne, tu pourrais utiliser directement ArrayList<Cellule>, dont tout le monde sait ce que c'est. Elle possède déjà une implémentation de toString() qui fera très bien l'affaire.
    Et si vraiment ça ne convient pas le toString() existant, il vaut mieux procéder par composition plutôt que par héritage :

    Ta classe Ligne devrait contenir une ArrayList<Cellule>, mais pas étendre ArrayList<Cellule>. Cela est beaucoup moins flexible et manque d'intérêt.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci thelvin pour ton explication

    Pour le ArrayList c'est plus une habitude que j'ai actuellement en Delphi, du coup je reste comme mon 1er code ou j'avais fait ce que tu indiques.

    L’intérêt était de pouvoir faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab.get(tab.size() - 1).get(j - 1).Value
    au lieu de ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab.get(tab.size() - 1).Cellules.get(j - 1).Value
    une simple histoire de fainéantise

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    C'est parfaitement normal, mais rien ne t'empêche de faire ta propre méthode get() qui délègue à cellules.get().

  5. #5
    Invité
    Invité(e)
    Par défaut
    Effectivement, je vais faire comme tu me l'indiques

    En Delphi la notion de création / libération est plus présente qu'en Java, cela permet de se passer d'un constructeur et destructeur c'était aussi pour cela que je les utilisaient, ici avec le GC cela est moins contraignant

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

Discussions similaires

  1. Classe pour la création d'un graphe xy
    Par Bob dans le forum MFC
    Réponses: 24
    Dernier message: 03/12/2009, 17h20
  2. Réponses: 6
    Dernier message: 22/11/2007, 19h46
  3. Réponses: 31
    Dernier message: 30/03/2006, 16h57
  4. Variable d'une Classe Ancêtre
    Par Génie dans le forum Langage
    Réponses: 3
    Dernier message: 18/09/2002, 19h24
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 17h21

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