1、Serializable序列化时不会调用默认的构造器,而Externalizable序列化时会调用默认构造器的!!!
2、Serializable:
一个对象想要被序列化,那么它的类就要实现 此接口,这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。
3、Externalizable:
他是Serializable接口的子类,有时我们不希望序列化那么多,可以使用这个接口,这个接口的writeExternal()和readExternal()方法可以指定序列化哪些属性。
4.关键字 transient[1]的作用及使用方法
In the Java programming language, transient is a keyword used as a field modifier[2]. When a field is declared transient, it would not be serialized even if the class to which it belongs is serialized. In Java, methods, classes and interfaces cannot be declared as transient, because they are never serialized.
[1]transient 美['trænziənt]英['trænziənt]adj.短暂的;转瞬即逝的;暂住的
n.暂住某地的人;过往旅客;临时工。 网络:瞬态;瞬时;暂态
[2]modifier> 美['mɑdɪ.faɪər]英['mɒdɪ.faɪə®]n.修饰语。 网络:修饰符;修饰词;
In Hibernate and other persistence systems, transient describes an object that has been instantiated, but is not associated with a Hibernate session, i. e. the object resides in memory but is not being persisted.[2]
Why does Java have transient fields?
The transient keyword in Java is used to indicate that a field should not be serialized. From the Java Language Specification, Java SE 7 Edition, Section 8.3.1.3. transient Fields: Variables may be marked transient to indicate that they are not part of the persistent state of an object.
java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String passwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public static void main(String[] args) throws IOException, InterruptedException {
User user = new User();
user.setUsername("larry");
user.setPasswd("password");
System.out.println("read before Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
try {
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("C:/user.txt"));
os.writeObject(user); // 将User对象写进文件
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
ObjectInputStream is = new ObjectInputStream(new FileInputStream(
"C:/user.txt"));
user = (User) is.readObject(); // 从流中读取User的数据
is.close();
System.out.println("\nread after Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
输出结果为:
read before Serializable:
username: larry
password: password
read after Serializable:
username: larry
password: null
密码字段为null,说明反序列化时根本没有从文件中获取到信息
5. transient使用总结
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
第三点注意(一个静态变量不管是否被transient修饰,均不能被序列化),反序列化后类中static型变量username的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的。
5. transient使用注意—被transient关键字修饰的变量不一定就是被序列化。
在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。