为何IOException无法覆盖FileNotFoundException?Java反序列化报错排查
问题原因及解决方法
一、外层未捕获到IOException的原因
你的deserialize方法内部已经通过catch (IOException i)捕获了所有IO异常(包括FileNotFoundException),捕获后仅打印堆栈并返回null,不会将异常抛出到方法外部。因此外层的try-catch块根本不会接收到IO异常,自然不会执行logger.info("The Cycles object was not detected")这段代码。
二、程序崩溃(NullPointerException)的原因
当文件不存在时,new FileInputStream()会抛出FileNotFoundException,被内部catch块捕获,此时fileIn和in两个对象都没有成功初始化,值为null。而finally块中直接调用in.close()和fileIn.close(),对null对象调用方法会触发NullPointerException,这个异常没有被任何代码捕获,最终导致程序崩溃。
修复方案
方案1:使用try-with-resources自动管理资源(推荐)
Java 7及以上支持try-with-resources语法,会自动关闭实现了AutoCloseable接口的资源,无需手动在finally块中处理,从根源避免空指针问题:
public static Cycles deserialize() throws IOException, ClassNotFoundException { String filePath = System.getProperty("user.home") + System.getProperty("file.separator") + ".cycles"; try (FileInputStream fileIn = new FileInputStream(filePath); ObjectInputStream in = new ObjectInputStream(fileIn)) { return (Cycles) in.readObject(); } }
此时方法会将IO异常和ClassNotFoundException抛出到外层,外层的try-catch就能正常捕获并输出日志:
Cycles cl; try { cl = Cycles.deserialize(); logger.info("The Cycles object was successfully deserialized"); } catch (IOException e2) { logger.info("The Cycles object was not detected"); // 后续处理逻辑 } catch (ClassNotFoundException e) { logger.info("Cycles类定义未找到"); // 处理类缺失的情况 }
方案2:手动处理finally块中的null判断
如果坚持要在方法内部捕获异常并返回null,需要在finally块中先判断资源对象是否为null,再调用close方法,同时单独处理close可能抛出的IO异常:
public static Cycles deserialize() { FileInputStream fileIn = null; ObjectInputStream in = null; try { fileIn = new FileInputStream( System.getProperty("user.home") + System.getProperty("file.separator") + ".cycles"); in = new ObjectInputStream(fileIn); return (Cycles) in.readObject(); } catch (IOException i) { i.printStackTrace(); return null; } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } finally { // 先关闭ObjectInputStream,再关闭FileInputStream,分别判断null try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fileIn != null) { fileIn.close(); } } catch (IOException e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者rozerro
相关产品推荐
相关产品推荐

