1.序列化的serialVersionUID
serialVersionUID如果不手工设置,编译器每次编译时会设置一个。这样当类修改后,,不不能用来发序列化之前版本的类序列化的对象。所以可以手工设置一个。
https://blog.csdn.net/u014750606/article/details/80040130
2. java 类实现Serializable和Externalizable的区别
这里列出其中一点,就是当类实现Externalizable时,通过ObjectInputStream.readObject()创建对象时,会调用被序列化对象的无参构造函数。而实现Serializable的类,在调用ObjectInputStream.readObject()方法时,不会调用无参或有参构造方法。
package io;
import java.io.*;
/**
* @Author Tom
* @Date 2020/12/11 17:36
* @Version 1.0
* @Description: //No constructor is called when using ois.readObject() to create object.
*/
public class Person implements Serializable {
public static void main(String[] args) {
Person tom = new Person("tom", 20);
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"D:\\Java\\IdeaProjects\\j2se\\resources\\person.txt"));
final ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"D:\\Java\\IdeaProjects\\j2se\\resources\\person.txt"));){
oos.writeObject(tom);
//No constructor is called when using ois.readObject() to create object.
Person tom2 = (Person)ois.readObject();
System.out.println(tom2);
System.out.println(tom == tom2);//false
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
String name;
int age;
public Person() {
System.out.println("Constructor \"Person()\" is invoked");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Constructor \"Person(String name, int age)\" is invoked");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package io;
import java.io.*;
/**
* @Author Tom
* @Date 2020/12/11 17:36
* @Version 1.0
* @Description: Constructor "Person()" is invoked
*/
public class PersonExternal implements Externalizable {
public static void main(String[] args) {
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Java\\IdeaProjects\\j2se\\resources\\person-external.txt"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Java\\IdeaProjects\\j2se\\resources\\person-external.txt"))) {
PersonExternal tom = new PersonExternal("tom", 20);
oos.writeObject(tom);
//Constructor "Person()" is invoked
// PersonExternal personExternal = (PersonExternal) ois.readObject();
Object o = ois.readObject();
System.out.println(o);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
String name;
int age;
public PersonExternal() {
System.out.println("Constructor \"Person()\" is invoked");
}
public PersonExternal(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Constructor \"Person(String name, int age)\" is invoked");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
out.writeInt(age);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.name = (String)in.readObject();
this.age = in.readInt();
}
}