序列化提供了存储和稍后重新创建对象的默认功能。它使用详细的格式定义要存储的整个对象图,例如,假设您有一个linkedList,代码如下所示,那么默认的序列化将发现所有链接的对象并进行序列化。在默认序列化中,对象完全由其存储的位构成,没有构造函数调用。ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("/Users/Desktop/files/temp.txt"));
oos.writeObject(linkedListHead); //writing head of linked list
oos.close();
但是,如果您希望有限制的序列化,或者不希望您的对象的某些部分被序列化,那么请使用Externalable。Externalable接口扩展了可序列化的接口,并添加了两个方法:writeExoun()和readExoun()。它们在序列化或反序列化时自动调用。在使用Externalable时,我们应该记住默认构造器应该是公共的,否则代码会抛出异常。请遵循以下代码:public class MyExternalizable implements Externalizable{private String userName;private String passWord;private Integer roll;
public MyExternalizable(){}public MyExternalizable(String userName, String passWord, Integer roll){
this.userName = userName;
this.passWord = passWord;
this.roll = roll;}@Overridepublic void writeExternal(ObjectOutput oo) throws IOException {
oo.writeObject(userName);
oo.writeObject(roll);}@Overridepublic void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException {
userName = (String)oi.readObject();
roll = (Integer)oi.readObject();}public String toString(){
StringBuilder b = new StringBuilder();
b.append("userName: ");
b.append(userName);
b.append(" passWord: ");
b.append(passWord);
b.append(" roll: ");
b.append(roll);
return b.toString();}public static void main(String[] args){
try
{
MyExternalizable m = new MyExternalizable("nikki", "student001", 20);
System.out.println(m.toString());
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Desktop/files/temp1.txt"));
oos.writeObject(m);
oos.close();
System.out.println("***********************************************************************");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Desktop/files/temp1.txt"));
MyExternalizable mm = (MyExternalizable)ois.readObject();
mm.toString();
System.out.println(mm.toString());
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}
catch(IOException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}}}
在这里,如果您注释默认构造器,那么代码将抛出在异常下面:java.io.InvalidClassException: javaserialization.MyExternalizable;
javaserialization.MyExternalizable; no valid constructor.
我们可以观察到,由于密码是敏感的信息,所以我不使用写外部(ObjectOutput Oo)方法对其进行序列化,也不会在readExoun(ObjectInput Oi)中设置它的值。这是Externalable提供的灵活性。
上述代码的输出如下:userName: nikki passWord: student001 roll: 20***********************************************************************userName:
nikki passWord: null roll: 20
我们可以观察到,因为我们没有设置密码的值,所以它是空的。
也可以通过将密码字段声明为瞬态来实现同样的目的。private transient String passWord;
希望能帮上忙。如果我犯了什么错,我道歉。谢谢。