Maison >Java >javaDidacticiel >Sérialisation JAVA
Si vous souhaitez écrire un objet dans un fichier, vous constatez que ni le flux d'octets ni le flux de caractères ne peuvent répondre aux exigences, Comment écrire des objets dans un fichier ?
Lorsque vous utilisez le flux de caractères d'octets, vous devez convertir l'objet en octets/caractères, puis l'écrire dans le fichier. Mais le flux de caractères d'octets n'a pas de méthode pour convertir l'objet en octets. ce?
Sérialisation Java : le processus de conversion d'objets en octets, qui répond exactement à mes besoins.
Désérialisation Java : le processus de restauration d'octets vers des objets
Cela satisfait notre désir d'écrire des objets dans des fichiers et de lire des objets
a. Écrivez l'objet sur le disque dur
b.Transférer entre les réseaux
Lorsque vous envoyez du texte. , audio, vidéo, etc. sont transmis sur le réseau, ils sont convertis en séquences binaires pour la transmission. Si nous voulons transmettre des objets sur le réseau, nous devons utiliser la sérialisation et la désérialisation pour répondre à l'envoi et à la réception des données.
###4. Avantages de la sérialisation et de la désérialisation
1. Obtenez la persistance des données et enregistrez en permanence les données sur le disque dur local grâce à la sérialisation
2. l'objet peut être transmis sur le réseau.
Interface sérialisable Là. n'est pas une méthode, elle fournit simplement un identifiant pour indiquer au mécanisme Java que la classe peut être sérialisée
;
Si cet identifiant n'est pas créé, le mécanisme Java en créera automatiquement un. SerialVersionUID génère un champ de hachage 64 bits basé sur le nom de la classe, le nom de l'interface, la méthode membre et l'attribut , etc. .
S'il n'y a pas de SerialVersionUID, nous constaterons généralement que si les attributs de la classe sont modifiés après la sérialisation, une erreur sera signalée lors de la désérialisation, car les attributs fatigués ont été modifiés, java Le mécanisme recréera un SerialVersionUID, ce qui entraînera une incohérence avec l'ID d'origine et un échec de désérialisation.
Si l'implémentation SerialVersionUID est définie, la compatibilité des versions est garantie Même si des attributs ou des méthodes sont ajoutés, la sérialisation et la désérialisation peuvent toujours être effectuées, Uniquement. la valeur de l'attribut nouvellement ajouté est nulle ou la valeur de l'attribut supprimé n'est pas affichée.
package com.chb.test;import java.io.Serializable;public class Student implements Serializable{ //序列化标识 private static final long serialVersionUID = 1L; private String name; private int age; private String sex; public Student() { } public Student(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } @Override public String toString() { return "Student{" +"姓名:"+this.name +"性别:"+this.sex +"年龄"+this.age + "}"; } /**setter getter 省略。。。*/ }
L'interface Serializalable fournit uniquement une représentation pour convertir des objets en séquences binaires et restaurer des séquences binaires. Les objets sont deux méthodes fournies par ObjectOutputStream et ObjectInputStream : writeObject() et readObject()
writeObject()
public static void write(Student s1) throws Exception { FileOutputStream fos = new FileOutputStream(filename); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(s1); oos.close(); }
readObject()
public static Student read() throws Exception { FileInputStream fis = new FileInputStream(filename); ObjectInputStream ois = new ObjectInputStream(fis); Student stu = new Student(); //使用readeObject()进行反序列化 stu= (Student) ois.readObject(); ois.close(); return stu; }
Dans certaines occasions, nous ne souhaitons pas sérialiser certains champs sensibles, ou membres de type référence d'un la classe ne peut pas être sérialisée. C'est pourquoi nous devons utiliser transient pour modifier ces membres afin d'éviter qu'ils ne soient sérialisés. Par exemple : objet compte bancaire, vous ne souhaitez pas sérialiser le montant du compte.
Modifiez la classe Student ci-dessus, modifiez l'attribut sex avec transitoire
transient private String sex;
puis sérialisez-le
Student s1 = new Student("roase",19, "女"); write(s1);
et désérialisez-le L'objet lu trouvé : le sexe est nul , indiquant que les attributs modifiés par transitoire ne seront pas sérialisés.
Pour l'âge du membre transitoire ci-dessus, que se passe-t-il si nous voulons qu'il puisse être sérialisé et désérialisé ici ? >
private void writeObject(ObjectOutputStream out) throws Exception{ out.defaultWriteObject(); out.writeInt(age); } private void readObject(ObjectInputStream in) throws Exception { in.defaultReadObject(); age=in.readInt(); }Dans le writeObject(), la méthode defaultWriteObject() dans ObjectOutputStream sera appelée en premier. Cette méthode exécutera le
mécanisme de sérialisation par défaut et le champ age sera ignoré. Appelez ensuite la méthode writeInt() pour écrire explicitement le champ age dans ObjectOutputStream. La fonction de readObject() est de lire des objets, et son principe est le même que la méthode writeObject(). Exécutez à nouveau l'application read() et vous obtiendrez le résultat suivant :
1 Question : Si vous souhaitez écrire un objet dans un. file , a constaté que ni le flux d'octets ni le flux de caractères ne peuvent répondre aux exigencesComment écrire des objets dans un fichier ? Lorsque vous utilisez le flux de caractères d'octets, vous devez convertir l'objet en octets/caractères, puis l'écrire dans le fichier. Mais le flux de caractères d'octets n'a pas de méthode pour convertir l'objet en octets. ce?
Java序列化:将对象转为字节的过程,这正好符合我的需求。
Java反序列化:将字节恢复为对象的过程
这满足我们想文件中写对象,和读取对象
a、将对象写道硬盘中;
b、网络间传输
当在网络上传送文本,音频,视频等,都是转化为二进制序列传送,我们要在网络上传送对象,就必须使用序列化和反序列化,满足数据的发送和接收。
###4、序列化和反序列化的好处
一、实现数据的持久化,通过序列化将数据永久的保存在本地的硬盘上;
二、实现远程网络通信,利用序列化,使得在网络上可以传输对象的字节序列。
Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;
如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段。
如果没有SerialVersionUID, 通常我们会发现,如果在序列化后,修改了类的属性, 在进行反序化,会报错,因为累的属性修改了,java机制会重新创建一个SerialVersionUID, 导致与原来的ID不一致, 反序列化失败。
如果设置了实现SerialVersionUID, 保证版本的兼容性, 即使添加了属性或方法, 仍然能进行序列化和反序列化, 只是新添加的属性值为null,或不显示被删除属性的值。
package com.chb.test;import java.io.Serializable;public class Student implements Serializable{ //序列化标识 private static final long serialVersionUID = 1L; private String name; private int age; private String sex; public Student() { } public Student(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } @Override public String toString() { return "Student{" +"姓名:"+this.name +"性别:"+this.sex +"年龄"+this.age + "}"; } /**setter getter 省略。。。*/ }
Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()
writeObject()
public static void write(Student s1) throws Exception { FileOutputStream fos = new FileOutputStream(filename); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(s1); oos.close(); }
readObject()
public static Student read() throws Exception { FileInputStream fis = new FileInputStream(filename); ObjectInputStream ois = new ObjectInputStream(fis); Student stu = new Student(); //使用readeObject()进行反序列化 stu= (Student) ois.readObject(); ois.close(); return stu; }
在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。
修改上面的Student类,将sex属性使用transient修饰
transient private String sex;
再进行序列化
Student s1 = new Student("roase",19, "女"); write(s1);
反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。
对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:
1、去掉transient的修饰
2、提供两个方法
private void writeObject(ObjectOutputStream out) throws Exception{ out.defaultWriteObject(); out.writeInt(age); } private void readObject(ObjectInputStream in) throws Exception { in.defaultReadObject(); age=in.readInt(); }
在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:
以上就是JAVA之序列化的内容,更多相关内容请关注PHP中文网(www.php.cn)!