Heim >Java >javaLernprogramm >13.Java-Grundlagen – Serialisierung
Bevor Sie die Serialisierung einführen, müssen Sie zunächst die folgenden Konzepte kennen:
Nichtpersistenz: Für Objekte, die in JVM (Java Virtual Machine) vorhanden sind, kann ihr interner Zustand nur im Speicher beibehalten werden funktioniert nicht mehr, der interne Zustand verschwindet, sodass er nicht dauerhaft ist.
Persistenz: Wenn Sie das Objekt dauerhaft speichern möchten (d. h. Persistenz), besteht der übliche Ansatz darin, es in einer Datei oder Datenbank.
serialisieren. Durch Serialisierung können Sie es einfach in der JVM serialisieren Das Objekt wird zur Speicherung in ein Byte-Array (Stream) konvertiert.
class Person implements Serializable { private String name; private int age; public Person(String name ,int age){ this.name = name; this.age =age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "name is " + name + " , age is " + age; } }public class Test { private final static String TEMPFILE = "E:" + File.separator + "test.txt"; public static void main(String[] args) { Person person = new Person("test",100); write(person); // 关键 -> 序列化之后重新对对象进行赋值 person = new Person("hello",999); read(person); // 输出结果: // name is test , age is 100,序列化成功 // 反序列化成功,name is test , age is 100 } // 通过 ObjectOutputStream 进行对象的序列化操作 private static void write(Person person) { try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(TEMPFILE)); oos.writeObject(person); oos.close(); System.out.println(person+",序列化成功"); } catch (Exception e) { e.printStackTrace(); } } // 通过 ObjectInputStream 进行对象的反序列化操作 private static void read(Person person) { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(TEMPFILE)); person = (Person) ois.readObject(); ois.close(); System.out.println("反序列化成功.,"+person); } catch (Exception e) { e.printStackTrace(); } } }Beobachten Sie die Ausgabeergebnisse. Wir weisen das Objekt nach der Serialisierung neu zu, und das Ergebnis der Deserialisierung ist immer noch dasselbe wie vor der Serialisierung. Die Werte sind konsistent, was auch indirekt beweist, dass das Objekt dauerhaft gespeichert ist und Persistenz erreicht wird.
nicht unserialisierbar ).
// 序列化过程、调用过程与上述例子一致,省略代码... // 这里只对内部类 Person 的 age 属性进行修改class Person implements Serializable { // 用 transient 修该变量 private transient int age; // 省略部分代码...} // 调用后的输出结果: // name is test , age is 100,序列化成功 // 反序列化成功.,name is test , age is 0Beobachten Sie die Ausgabeergebnisse und stellen Sie fest, dass das Alter vor der Serialisierung 100 beträgt, während das durch die Deserialisierung gelesene Alter 0 beträgt. Der Anfangswert des Parameters vom Typ int ist 0, was bedeutet, dass der Parameter nicht serialisiert wurde.
bedeutet nicht, dass sie nicht serialisiert werden können ).
// 序列化过程、调用过程与上述例子一致,省略代码... // 这里只对内部类 Person 的 name 属性进行修改class Person implements Serializable { // 用 static 修该变量 private static String name; // 省略部分代码...} // 输出结果: // name is test , age is 100,序列化成功//反序列化成功.,name is hello , age is 100Beobachten Sie die Ausgabeergebnisse und stellen Sie fest, dass der Wert von name „Hallo“ lautet und nicht „Test vor der Serialisierung“. Die unterschiedlichen Werte davor und danach zeigen an, dass es nicht serialisiert wurde. Und da die Eigenschaften von static mit Klassen zusammenhängen, wurde die Variable nach der Serialisierungsoperation neu zugewiesen, was dazu führte, dass ihr Wert nicht null, sondern „Hallo“ war.
nicht serialisiert werden.
// 序列化过程、调用过程与上述例子一致,省略代码... // 这里只对内部类 Person 的 name 属性进行修改class Person implements Serializable { //新增成员变量 private Thread myThread = new Thread(); //省略部分代码...} // 输出结果(抛出异常): // Caused by: java.io.NotSerializableException: java.lang.Thread
// 序列化操作代码与上面一致... // 这里只对内部类 Person 的属性进行修改。class Person implements Serializable { private static String name; private transient int age; // 自定义序列化操作 private void writeObject(ObjectOutputStream out) throws IOException{ out.defaultWriteObject(); out.writeObject(name); out.writeInt(age); } // 自定义反序列化操作 private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException{ in.defaultReadObject(); name = (String) in.readObject(); age = in.readInt(); } // 省略部分代码...} // 输出结果: // name is test , age is 100,序列化成功 // 反序列化成功,name is test , age is 100
writeExternal und readExternal für benutzerdefinierte Serialisierung und Deserialisierungsprozess.
parameterlosen Konstruktor enthalten muss.
// 序列化操作代码与上面一致,这里只对内部类 Person 的进行修改。 class Person implements Externalizable { private static String name; private transient int age; // 重点 ->必须有无参构造函数 public Person(){ } public Person(String name ,int age){ this.name = name; this.age =age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "name is " + name + " , age is " + age; } // 实现接口的方法 @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeInt(age); } // 实现接口的方法 @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); age = in.readInt(); } } // 输出结果: // name is test , age is 100,序列化成功 // 反序列化成功,name is test , age is 100
-Methode geändert wird, bleibt die serialVersionUID ** unverändert **.
-Attribut des Objekts geändert wird, ändert sich die neu generierte serialVersionUID**.
因此说明序列化是作用于对象属性上的。
下面通过实例来探究下 serialVersionUID 的具体作用:
首先我们对对象进行序列化操作(这里取消了反序列化的操作)
// 序列化操作代码与上面例子一致...// 这里取消了反序列化的操作public static void main(String[] args) { Person person = new Person("test",100); write(person); person = new Person("java", 200); //read(person);}
然后新增一个对象的属性,再进行反序列化操作
// 省略部分代码,与上面的代码一致...class Person implements Serializable { private String name; private age; //新增成员变量 private int phone; //省略部分代码... } }public static void main(String[] args) { Person person = new Person("test",100); //write(person); person = new Person("java", 200); read(person); }// 输出结果(抛出异常):// java.io.InvalidClassException: Person;
观察代码,在序列化对象并没有添加 serialVersionUID 的情况,在对象序列化之后如果改变了对象的属性,反序列化就会抛出异常。如果对象添加了 serialVersionUID 就不会出现这种情况,这里就不验证了。
以上就是13.Java 基础 - 序列化的内容,更多相关内容请关注PHP中文网(www.php.cn)!