我正在尝试理解Java序列化机制,我对此几乎没有疑问和错误。“ java.io.NotActiveException:不能调用writeObject”
package serialization;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class WriteObject{
private void writeObject(ObjectOutputStream oos)
throws IOException {
// default serialization
oos.defaultWriteObject();
Address address = new Address();
address.setStreet("wall street");
address.setCountry("united states");
address.setNameofperson("nameofperson");
oos.writeObject(address);}
public static void main (String args[]) {
Address address = new Address();
address.setStreet("wall street");
address.setCountry("united states");
address.setNameofperson("nameofperson");
//address.pet="lucy";
WriteObject wr= new WriteObject();
try{
File f = new File("C:fileaddress.ser");
//f.createNewFile();
FileOutputStream fout = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fout);
wr.writeObject(oos);
//oos.defaultWriteObject();
oos.close();
System.out.println("Done");
}catch(Exception ex){
ex.printStackTrace();
}
}
}
我收到以下错误:
constructor default pers
constructor default add
java.io.NotActiveException: not in call to writeObject
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at serialization.WriteObject.writeObject(WriteObject.java:13)
at serialization.WriteObject.main(WriteObject.java:34)
也请回答以下有关Java序列化的问题:
oos.defaultWriteObject();
?根据{{3}},此处存在向后兼容性。我还不太了解它是如何实现的。序列化的不兼容更改之一是删除较新版本中的字段。这意味着旧版本将不得不设置有时对用户无效的默认值。这与新版本添加一个新字段并允许设置默认值有何不同?oos.defaultWriteObject();
和oos.writeObject(address);
会不会有什么区别?我的意思是都将所有超类和当前类的非瞬态非静态字段都写入OOS。答案 0 :(得分:0)
writeObject
不是为了向后兼容。 readObject
是。defaultWriteObject
可以帮助您快速编写“可序列化”的值。考虑您的bean添加了一个新字段。
class Bean implements Serializable {
int id;
String name;
String newValue = "123";
}
尽管您提供了newValue
默认值,但是Java序列化将忽略它。 (因为它分配实例而不是new
)
现在,如果您不使用readObject
,您将得到newValue=null
。因此,您还需要在readObject
进行初始化。
private void readObject(ObjectInputStream stream) throws Exception {
stream.defaultReadObject();
this.newValue = "123";
}
defaultWriteObject
如何为您提供帮助考虑您的bean除了某些字段外几乎可以“序列化”。
请参见以下代码。 BadThing
不是Serializable
,或者其中包含一些您不想序列化的敏感数据。
class Bean implements Serializable {
int id;
String string;
BadThing badThing;
}
要快速序列化它,可以让字段transient
并编写writeObject
方法来处理它
private void writeObject(ObjectOutputStream stream) throws Exception {
stream.defaultWriteObject();
stream.writeInt(badThing.id);
}
// Corresponding `readObject`
您当然可以将defaultWriteObject
替换为多个writeXXX
。但是,如果您有很多领域,那么编写代码既累又无聊,对吧?
所以defaultWriteObject
只是为了使您免于编写无聊的代码。