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 :

[Serialisation] methode générique ?


Sujet :

avec Java

  1. #1
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut [Serialisation] methode générique ?
    Bonjour,

    Suite à ce cour sur la sérialisation, j'ai souhaité le mettre en application et je me posais une question.

    Est-il possible de faire une fonction qui permettrait de sérialiser n'importe quel objet qui implémenterai le serializable ?

    quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void serializer(Object o){
    Prenons deux classes. Avion et Bateau.

    Actuellement, j'utiliserai ceci pour faire la sérialisation :
    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 void serializerAvion(Avion a){
            try {
                // ouverture d'un flux de sortie vers le fichier "avion.serial"
                FileOutputStream fos = new FileOutputStream("avion.serial");
     
                // création d'un "flux objet" avec le flux fichier
                ObjectOutputStream oos= new ObjectOutputStream(fos);
                try {
                    // sérialisation : écriture de l'objet dans le flux de sortie
                    oos.writeObject(a);
                    // on vide le tampon
                    oos.flush();
                    System.out.println(a + " a ete serialise");
                } finally {
                    //fermeture des flux
                    try {
                        oos.close();
                    } finally {
                        fos.close();
                    }
                }
            }
            catch(IOException ioe) {
                ioe.printStackTrace();
            }
        }
    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 void serializerBateau(Bateau b){
            try {
                // ouverture d'un flux de sortie vers le fichier "bateau.serial"
                FileOutputStream fos = new FileOutputStream("bateau.serial");
     
                // création d'un "flux objet" avec le flux fichier
                ObjectOutputStream oos= new ObjectOutputStream(fos);
                try {
                    // sérialisation : écriture de l'objet dans le flux de sortie
                    oos.writeObject(b);
                    // on vide le tampon
                    oos.flush();
                    System.out.println(b + " a ete serialise");
                } finally {
                    //fermeture des flux
                    try {
                        oos.close();
                    } finally {
                        fos.close();
                    }
                }
            }
            catch(IOException ioe) {
                ioe.printStackTrace();
            }
        }
    Si j'avais 36 classes, je serais obligé de décrire 36 méthodes... pour rien >.<

    Comment pourrais-je rendre cette sérialisation générique ?

    Merci à vous
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  2. #2
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut Utiliser les generics??
    Salut,
    juste une petite remarque, les deux méthodes ne diffèrent que du type d'objet à sérialiser, peut être que faire une méthode générique ferait l'affaire, quelque chose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public <T> void serializerAvion(T t, String fichierSortie)
    .
    Je ne sais si j'ai bien compris la question, mais bon, j'espère que c'est ce que tu cherchais.

  3. #3
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    xD

    En effet, je demandais s'il pouvait être utilisé une méthode générique.

    T représente quelque chose de particulier ? Une classe spécifique ou justement le terme générique ?
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  4. #4
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    Nickel, c'est bien ce que je souhaitais ^^

    Mais si tu peux me donner un ou deux renseignements sur <T>
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  5. #5
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut
    Resalut,
    tu sais, c'est toi qui a plein d'étoiles

    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 <T> void serializerObjet(T t, String fichierSortie)
    {
    try {
                // ouverture d'un flux de sortie vers le fichier "avion.serial"
                FileOutputStream fos = new FileOutputStream(fichierSortie);
     
                // création d'un "flux objet" avec le flux fichier
                ObjectOutputStream oos= new ObjectOutputStream(fos);
                try {
                    // sérialisation : écriture de l'objet dans le flux de sortie
                    oos.writeObject(t);
                    // on vide le tampon
                    oos.flush();
                    System.out.println(t + " a ete serialise");
                } finally {
                    //fermeture des flux
                    try {
                        oos.close();
                    } finally {
                        fos.close();
                    }
                }
            }
            catch(IOException ioe) {
                ioe.printStackTrace();
            }
        }
     
    }
    T représente la classe qui sera donné en paramètre; par exp, si on met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    serializerObjet(Avion a, "avion.serial");
    T sera remplacé par Avion, et ainsi de suite.
    Rmq: j'ai pas testé le code ci-dessus, mais je crois que c'est correcte ( suis trop paresseux )
    Voilà, j'espère que ça aidera.

  6. #6
    Inactif   Avatar de Deallyra
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    1 997
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 1 997
    Par défaut
    Nan mais j'avais bien modifié mon code xD

    Je voulais juste savoir à quoi correspondait le T

    java.lang
    Class Class<T>

    java.lang.Object
    extended by java.lang.Class<T>

    Type Parameters:
    T - the type of the class modeled by this Class object. For example, the type of String.class is Class<String>. Use Class<?> if the class being modeled is unknown.

    All Implemented Interfaces:
    Serializable, AnnotatedElement, GenericDeclaration, Type

    __________________________

    public final class Class<T>
    extends Object
    implements Serializable, GenericDeclaration, Type, AnnotatedElement

    Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

    Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.

    The following example uses a Class object to print the class name of an object:

    void printClassName(Object obj) {
    System.out.println("The class of " + obj +
    " is " + obj.getClass().getName());
    }


    It is also possible to get the Class object for a named type (or for void) using a class literal (JLS Section 15.8.2). For example:

    System.out.println("The name of class Foo is: "+Foo.class.getName());
    *Si la réponse vous convient, n'oubliez pas le tag
    *Exprimez vous dans un français correct; on prend le temps de vous lire, prenez le temps de bien écrire.
    *Et comment on interprète votre code? N'oubliez pas la balise!

    *Pour une mise en page simple avec des divs.
    *Pour faire des formulaires xHTML CSS.

  7. #7
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Bonjour,

    Je ne vois pas pourquoi dans la solution proposée, vous utilisez les Generics. Les méthodes du premier message ne retournent rien. De plus l'appelant de la méthode connait l'objet à sérialiser donc il n'y a pas besoin de le renvoyer.

    Donc pour faire simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        public static void serializer(Serializable o, String fichier) throws IOException {
            try { // try/catch pour logger l'exception
             ObjectOutput os = new ObjectOutputStream(new FileOutputStream(fichier));
             try { // try/finally pour bien fermer os
                 os.writeObject(o);
             } finally {
                 os.close();
             }
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            }
        }
    Je rajouterai que l'appel à flush n'est pas nécessaire : la méthode close l'appelle. De plus la fermeture du ObjectOutputStream entraine la fermeture du FileOutputStream => il n'est donc pas nécessaire de fermer les deux explicitement.


    Gronono.

  8. #8
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut
    Salut,
    tu as peut être raison, mais je crois qu'il est tout de même mieux d'utiliser les generics. Avec les generics, on peut restreindre les types passés en argument en mettant par exp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <T extends UneClasse> void serializerObjet(T t, String fichierSortie)
    je crois que c'est mieux, et c'est généralement déconseillé de passer en argument des Object, et je crois que ça s'applique aussi pour Serializable.

  9. #9
    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,

    Citation Envoyé par gronono Voir le message
    De plus la fermeture du ObjectOutputStream entraine la fermeture du FileOutputStream => il n'est donc pas nécessaire de fermer les deux explicitement.
    Oui et non... Si on veut vraiment pinailler il faudrait séparer les deux, car les ObjectInput/OutputStream ont la particularité d'effectuer des accès I/O dans leurs constructeurs, ce qui fait que leurs constructeurs peuvent remonter une exception ce qui empêcherait la fermeture du FileStream pourtant bien ouvert...

    Mais bon c'est vraiment pour pinailler...


    Citation Envoyé par herch Voir le message
    tu as peut être raison, mais je crois qu'il est tout de même mieux d'utiliser les generics. Avec les generics, on peut restreindre les types passés en argument en mettant par exp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <T extends UneClasse> void serializerObjet(T t, String fichierSortie)
    Dans ce cas précis, les Generics n'apportent rien par rapport à un typage standard des paramètres. En clair ton code ci dessous n'apporte rien par rapport à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void serializerObjet(UneClasse t, String fichierSortie)
    Citation Envoyé par herch Voir le message
    je crois que c'est mieux, et c'est généralement déconseillé de passer en argument des Object, et je crois que ça s'applique aussi pour Serializable.
    Pourquoi ?
    Si une méthode accepte tout type d'objet c'est logique d'utiliser Object... de même que Serializable si la méthode accepte n'importe quel objet Serializable...



    Les Generics sont utiles lorsqu'ils permettent de limiter le type de plusieurs paramètres et/ou du type de retour selon plusieurs autres paramètres.




    A la rigueur on pourrait s'en servir lors de la désérialisation pour cacher le cast :
    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
    	public static <T> T unserialize(String fichier) throws IOException, ClassNotFoundException {
        	FileInputStream fis = new FileInputStream(fichier);
        	try {
        		ObjectInputStream ois = new ObjectInputStream(fis);
        		try {
        			@SuppressWarnings("unchecked")
        			T result = (T) ois.readObject();
        			return result;
        		} finally {
        			ois.close();
        		}
        	} finally {
        		fis.close();
        	}
        }
    Ce qui permettrait d'utiliser la méthode sans cast :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	String string = unserialize("fichier1");
    	Number number = unserialize("fichier1");
    	MyObject object = unserialize("fichier1");
    (par contre cela risque de générer des ClassCastException à l'exécution si les types ne correspondent pas )

    a++

  10. #10
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut
    Salut,
    la question était de pouvoir utiliser une seule méthode pour sérialiser plusieurs objets
    Dans ce cas précis, les Generics n'apportent rien par rapport à un typage standard des paramètres. En clair ton code ci dessous n'apporte rien par rapport à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void serializerObjet(UneClasse t, String fichierSortie)
    je crois que c'est pas vraiment la réponse à la question, et je crois que les generics sont bien à leur place ici.
    La question qui se pose est : Doit-on utiliser les generics ou simplement passer un Object ou un Serializable à la méthode serializerObjet??

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

Discussions similaires

  1. Webservice / Serialisation / Type générique / Héritage
    Par XAMLdev dans le forum Services Web
    Réponses: 4
    Dernier message: 26/06/2012, 11h40
  2. methode générique set?
    Par kawe22 dans le forum Langage
    Réponses: 3
    Dernier message: 19/10/2010, 19h53
  3. Réponses: 2
    Dernier message: 27/04/2010, 16h58
  4. Réponses: 4
    Dernier message: 04/06/2008, 23h56
  5. Réponses: 9
    Dernier message: 16/10/2007, 01h26

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