更新
感谢大家的大力帮助,在这里我必须添加一个关于异常的可能原因:
如果您在域类中添加readObject()
和writeObject()
(如下面的类大学),并且您必须ObjectOutputStream.writeObject()
在 main() 方法中调用方法,那么请确保:
---不要将ObjectOutputStream.close()
方法放在域类中。它将导致异常,因为由于该对象已关闭,因此对该对象进行操作是非法的(程序如何读取文件或在文件已关闭后关闭文件?)。
我知道这是一个小问题,但调试起来非常微妙,因为异常不会说明任何事情。因此,这是记录在案的一点点。
我尝试实现一个简单的片段来破坏瞬态对象的序列化,即序列化瞬态对象的原始字段,然后通过 ObjectInputStream 反序列化这些原始字段,最后用它们组成一个新对象。场景是这样的:
public class College implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private transient City city; //transient
private String zipCode;
// constructors & getter/setters
private void writeObject(ObjectOutputStream os){
try {
os.defaultWriteObject();
os.writeInt(city.getCode());
os.writeInt(city.getPopulation());
os.writeObject(city.getName());
os.flush();
os.close(); // update: not good practice, may throw exception.
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void readObject(ObjectInputStream os){
try {
os.defaultReadObject();
int code = os.readInt();
int population = os.readInt();
String name = (String)os.readObject();
City theCity = new City(code, name, population);
System.out.println(theCity.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里是城市类
public class City {
// the primitive & String fields
private int code;
private String name;
private int population;
// getter/setters
}
这是编写和读取college
对象的可爱代码(有点笨拙,抱歉)
public class GeneralTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
City city = new City(375, "New York", 380897);
College college = new College("NYU", city, "10289");
College readCollege = null;
City readCity = null;
System.out.println("Before serialization -- City: ["+city.toString()+"], College: ["+college.toString()+"]");
try {
FileOutputStream fs = new FileOutputStream("college.foo");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(college);
os.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream("college.foo");
ObjectInputStream ois = new ObjectInputStream(fis);
readCollege = (College)ois.readObject();
//get values to compose a city object
int id = ois.readInt();
int population = ois.readInt();
String name = ois.readUTF();
readCity = new City(id, name, population);
ois.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("After serialization -- City: ["+readCity.toString()+"], College: ["+readCollege.toString()+"]");
}
}
然后我得到了这个异常并且readCollege
andreadCity
显然是空的:(
java.io.IOException: Write error
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:282)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1257)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1211)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1395)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:333)
at serialized.GeneralTest.main(GeneralTest.java:27)
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.readByte(ObjectInputStream.java:2721)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFChar(ObjectInputStream.java:3113)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3010)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2819)
at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1050)
at serialized.College.readObject(College.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at serialized.GeneralTest.main(GeneralTest.java:40)
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2553)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1899)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1873)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at serialized.GeneralTest.main(GeneralTest.java:40)
Exception in thread "main" java.lang.NullPointerException
at serialized.GeneralTest.main(GeneralTest.java:52)
有任何想法吗?提前致谢。