反序列化java.math.BigDecimal时遇InvalidClassException错误求助
解决java.math.BigDecimal反序列化时的serialVersionUID不匹配问题
首先咱们直接戳破核心问题:你用来写入序列化数据的代码用了字符流处理二进制内容,这直接破坏了序列化后的字节数据,才导致反序列化时出现看似serialVersionUID不匹配的错误。
为什么会出现这个诡异的错误?
序列化生成的是纯二进制字节流,而你用的FileWriter和InputStreamReader是字符流——它们会把字节按照系统默认的字符编码(比如UTF-8)转换成字符再写入文件。但二进制序列化数据里的很多字节序列根本不是合法的字符,转换过程中会被篡改、丢失或替换成默认占位符(比如�)。等你再读取这些被破坏的数据反序列化时,JVM拿到的已经不是原本的序列化内容,自然会抛出类版本不匹配的异常,看起来像是BigDecimal的serialVersionUID不对,但本质是数据已经彻底损坏了。
怎么修复?
把写入文件的代码改成用字节流处理,完全避开字符编码的转换。替换你的write方法为下面的实现:
static void write(File file, InputStream is) throws IOException { FileOutputStream fos = null; BufferedInputStream bis = null; try { fos = new FileOutputStream(file, true); bis = new BufferedInputStream(is); byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = bis.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } } finally { close(bis); close(fos); } }
关键修改点:
- 用
FileOutputStream(字节输出流)替代FileWriter,直接写入二进制数据 - 用
BufferedInputStream(字节输入流)替代InputStreamReader,直接读取二进制字节 - 用
byte[]缓冲区替代char[],确保数据以字节为单位完整传输
额外注意事项
- 之前用错误方式写入的文件已经损坏,无法修复,需要重新生成序列化数据并写入
- 所有序列化相关的IO操作都应该用字节流,绝对不要用字符流处理二进制序列化内容
内容的提问来源于stack exchange,提问作者AJPerez
相关产品推荐
相关产品推荐

