之前在复习深拷贝和反序列化时, 自己心血来潮照着网上的教程掐头去尾写了一段反序列化的代码。
class B implements Serializable {
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeInt(this.a);
}
}
解决方案也很简单:
如果要自定义writeObject方法, 就必须也自定义readObject方法, 不然会调用默认的readObject继续往后读取字段, 但是此时已经读到文件末了(-1), 所以就抛异常啦。
后面是我姐姐这个问题过程:
基本思路是将要反序列化的类实现Serializable, 然后用ObjectOutStream写到文件里, 再用ObjectInputStream从文件里读出来, 调用readObject()的时候发现抛出java.io.EOFException异常。
然后找到了下面的文章:
java.io.EOFException异常关于反序列化时抛出java.io.EOFException异常
问题描述:在反序列化对象时,当对象出入流将文件的全部类反序列化之后,始终会抛出java.io.EOFException.
原因:java API文档中对于反序列化对象时使用的java.io.ObjectInputStream类的readObject()方法的描述有一句话是"该方法始终会抛出异常",也就是说该异常无法避免的.
解决方法:
该异常是输入流已经到结尾了的标志,我们可以将其捕获,然后不做任何操作,即结束了该次反序列化操作,代码如下:
1 ObjectInputStream ois = null; 2 FileInputStream fis=new FileInputStream(filePath); 3 //当文件中的有内容时 4 if(fis.available()!=0) 5 ois = new ObjectInputStream(fis); 6 else{ 7 System.out.println("文件为空!"); 8 return ; 9 } 10 try{ 11 while(true) 12 System.out.println((Student)ois.readObject()); 13 }catch(EOFException e){ 14 }ps:在创建ObjectInputStream对象时,如果文件中没有内容,同样也会抛出java.io.EOFException
上面文章说readObject总是抛出这个异常, 给出的姐姐方案就是catch掉然后不管, 我想的是如果总是走到catch里, 我写的代码不就永远不能赋值给变量么:
try { // final ObjectInputStream input = new ObjectInputStream(new FileInputStream("./b.obj")); final ObjectInputStream input = new ObjectInputStream(pipedInputStream); final B o = (B) input.readObject(); System.out.println(o); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
final B o永远得不到赋值。 百思不得其姐。
我试着把writeObject方法注释掉, 发现居然把问题姐姐了。程序正常跑起来了。
后来细细一想, 应该是只自定义要序列化哪些字段, 但是反序列化不自定义的话,应该就会按照默认的去走, 进而引起报错。