Heim > Java > javaLernprogramm > Hauptteil

JAVA-Serialisierung

黄舟
Freigeben: 2017-02-24 09:44:30
Original
1524 Leute haben es durchsucht

1. Problem:

Wenn Sie ein Objekt in eine Datei schreiben möchten, stellen Sie fest, dass weder der Byte-Stream noch der Zeichen-Stream die Anforderungen erfüllen können Anforderungen. Wie schreibe ich Objekte in eine Datei?
Bei Verwendung des Byte-Zeichenstroms müssen Sie das Objekt in Bytes/Zeichen konvertieren und es dann in die Datei schreiben. Der Byte-Zeichenstrom verfügt jedoch nicht über eine Methode zum Konvertieren des Objekts in Bytes Mach das?

2. Serialisierung und Deserialisierung

Java-Serialisierung: der Prozess der Konvertierung von Objekten in Bytes, der genau meinen Anforderungen entspricht.
Java-Deserialisierung: der Prozess der Wiederherstellung von Bytes in Objekten
Dies erfüllt unseren Wunsch, Objekte in Dateien zu schreiben und Objekte zu lesen

3, Serialisierungs- und Deserialisierungs-Nutzungsszenarien

  • a. Schreiben Sie das Objekt auf die Festplatte

  • B. Übertragung zwischen Netzwerken

    • Wenn Text , Audio, Video usw. werden über das Netzwerk übertragen und zur Übertragung in Binärsequenzen umgewandelt. Wenn wir Objekte über das Netzwerk übertragen möchten, müssen wir Serialisierung und Deserialisierung verwenden, um das Senden und Empfangen von Daten zu ermöglichen.
    • ###4. Vorteile der Serialisierung und Deserialisierung

      Erzielen Sie Datenpersistenz und speichern Sie Daten dauerhaft auf der lokalen Festplatte durch Serialisierung Das Objekt kann über das Netzwerk übertragen werden.


    • So implementieren Sie Serialisierung und Deserialisierung
5.1. Implementieren Sie die

Serialisierbare Schnittstelle

Serialisierbare Schnittstelle ist keine Methode, sondern stellt lediglich einen Bezeichner bereit, um dem Java-Mechanismus mitzuteilen, dass die Klasse serialisiert werden kann Wenn dieser Bezeichner nicht erstellt wird, erstellt der Java-Mechanismus automatisch ein 64-Bit-Hash-Feld

basierend auf dem

Klassennamen, dem Schnittstellennamen, der Mitgliedsmethode und dem Attribut
usw . Wenn keine SerialVersionUID vorhanden ist, werden wir normalerweise feststellen, dass bei der Deserialisierung ein Fehler gemeldet wird, wenn die Attribute der Klasse nach der Serialisierung geändert werden, da die veralteten Attribute geändert wurden. java Der Mechanismus erstellt eine SerialVersionUID neu, was zu einer Inkonsistenz mit der ursprünglichen ID und einem Deserialisierungsfehler führt.


  • Wenn die Implementierung SerialVersionUID festgelegt ist, ist die Versionskompatibilität gewährleistet. Auch wenn Attribute oder Methoden hinzugefügt werden, kann die Serialisierung und Deserialisierung weiterhin durchgeführt werden,
  • Nur Der Wert des neu hinzugefügten Attributs ist null oder der Wert des gelöschten Attributs wird nicht angezeigt.
    • 5.2. ObjectOutputStream und ObjectInputStream
Die Serializalable-Schnittstelle bietet nur eine Darstellung zum Konvertieren von Objekten in Binärsequenzen und zum Wiederherstellen von Binärsequenzen. Objekte sind zwei Methoden, die von ObjectOutputStream und ObjectInputStream bereitgestellt werden: writeObject() und readObject()
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 省略。。。*/    
    }
Nach dem Login kopieren

writeObject()

readObject()
public static void write(Student s1) throws Exception {
        FileOutputStream fos = new FileOutputStream(filename);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(s1);
        oos.close();
}
Nach dem Login kopieren
Nach dem Login kopieren
  • 6. transient
In manchen Fällen möchten wir einige sensible Felder oder Referenztypmitglieder von a nicht serialisieren Die Klasse kann nicht serialisiert werden. Aus diesem Grund müssen wir
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;
}
Nach dem Login kopieren
Nach dem Login kopieren
transient

verwenden, um diese Mitglieder zu ändern, um zu verhindern, dass sie serialisiert werden. Beispiel: Bankkontoobjekt, Sie möchten den Kontobetrag nicht serialisieren.

Ändern Sie die obige Student-Klasse, ändern Sie das Geschlechtsattribut mit transient

und serialisieren Sie es dann

transient private String sex;
Nach dem Login kopieren
Nach dem Login kopieren
und deserialisieren Sie das gefundene Leseobjekt: Geschlecht ist null. Dies gibt an, dass durch transient geänderte Attribute nicht serialisiert werden.

Student s1 = new Student("roase",19, "女");
write(s1);
Nach dem Login kopieren
Nach dem Login kopieren

6.1 defaultWriteObject und defaultReadObject()
JAVA-SerialisierungWas ist, wenn wir möchten, dass es hier serialisiert und deserialisiert werden kann?

1. Entfernen Sie die vorübergehende Änderung

  • 2. Stellen Sie zwei Methoden bereit

  • Im writeObject()-Methode wird zuerst die defaultWriteObject()-Methode in ObjectOutputStream aufgerufen. Diese Methode führt den
  • Standardserialisierungsmechanismus
aus und das Altersfeld wird ignoriert. Rufen Sie dann die Methode writeInt() auf, um das Altersfeld explizit in den ObjectOutputStream zu schreiben. Die Funktion von readObject() besteht darin, Objekte zu lesen, und ihr Prinzip ist das gleiche wie das der Methode writeObject(). Führen Sie die Anwendung read() erneut aus und es wird die folgende Ausgabe angezeigt:
    private void writeObject(ObjectOutputStream out) throws Exception{        
    out.defaultWriteObject();        
    out.writeInt(age);
    }    
    private void  readObject(ObjectInputStream in) throws Exception {        
    in.defaultReadObject();
        age=in.readInt();
    }
Nach dem Login kopieren
Nach dem Login kopieren

1 Frage:

JAVA-Serialisierung Wenn Sie ein Objekt in a schreiben möchten Datei habe festgestellt, dass weder der Byte-Stream noch der Zeichen-Stream die Anforderungen erfüllen können.

Wie schreibe ich Objekte in eine Datei?

Bei Verwendung des Byte-Zeichenstroms müssen Sie das Objekt in Bytes/Zeichen konvertieren und es dann in die Datei schreiben. Der Byte-Zeichenstrom verfügt jedoch nicht über eine Methode zum Konvertieren des Objekts in Bytes Mach das?

2、序列化与反序列化

Java序列化:将对象转为字节的过程,这正好符合我的需求。
Java反序列化:将字节恢复为对象的过程
这满足我们想文件中写对象,和读取对象

3、序列化和反序列化的使用场景

  • a、将对象写道硬盘中;

  • b、网络间传输

    • 当在网络上传送文本,音频,视频等,都是转化为二进制序列传送,我们要在网络上传送对象,就必须使用序列化和反序列化,满足数据的发送和接收。
      ###4、序列化和反序列化的好处
      一、实现数据的持久化,通过序列化将数据永久的保存在本地的硬盘上;
      二、实现远程网络通信,利用序列化,使得在网络上可以传输对象的字节序列。

5、如何实现序列化和反序列化

5.1 、实现Serializable接口

  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 省略。。。*/    }
Nach dem Login kopieren

5.2、ObjectOutputStream与ObjectInputStream

  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();
}
Nach dem Login kopieren
Nach dem Login kopieren
  • 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;
}
Nach dem Login kopieren
Nach dem Login kopieren

6、transient

在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。
修改上面的Student类,将sex属性使用transient修饰

transient private String sex;
Nach dem Login kopieren
Nach dem Login kopieren

再进行序列化

Student s1 = new Student("roase",19, "女");
write(s1);
Nach dem Login kopieren
Nach dem Login kopieren

反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。
JAVA-Serialisierung

6.1 defaultWriteObject和defaultReadObject()

对于上面的被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();
    }
Nach dem Login kopieren
Nach dem Login kopieren

在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

JAVA-Serialisierung

 以上就是JAVA之序列化的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage