Java中try-catch的核心是精准捕获可预期的外部异常,而非掩盖逻辑错误;应按子类到父类排列多个catch,善用try-with-resources自动管理资源,避免空catch。

Java中使用try-catch语句的核心,是把可能抛出异常的代码放进try块,再用catch块针对性地处理对应类型的异常。关键不是“包住所有代码”,而是明确哪里可能出错、想怎么恢复或反馈。
try-catch的基本结构与执行顺序
try块中的代码一旦抛出异常,会立刻中断执行,JVM按顺序查找匹配的catch块(从上到下,类型精确匹配或向上转型匹配)。如果找到,就执行该catch里的语句;没找到且有finally,仍会执行finally(除非遇到系统退出等极端情况)。
- 一个
try可以跟多个catch,建议按子类到父类排列,避免父类catch提前截获子类异常 -
catch参数必须是Throwable的子类,常用的是Exception及其子类(如IOException、NumberFormatException) -
finally块无论是否异常都会执行,适合释放资源(如关闭文件、数据库连接),但JDK 7+更推荐用try-with-resources
什么时候该用try-catch,什么时候不该用
不是所有异常都适合捕获。运行时异常(RuntimeException及其子类,如NullPointerException、ArrayIndexOutOfBoundsException)通常反映程序逻辑错误,应通过修复代码来避免,而不是靠catch掩盖问题。
- 适合捕获:可预期的外部干扰,比如读文件失败(
IOException)、网络超时(SocketTimeoutException)、用户输入格式不对(NumberFormatException) - 不适合捕获:空指针、数组越界、类型转换失败等——这些该在开发阶段用测试和校验提前发现
- 若只是记录日志后重新抛出,优先用
throw原异常,或用throw new XXXException("提示", e)包装,保留原始堆栈
try-with-resources:更安全的资源管理方式
手动在finally里关流容易出错(比如close()本身又抛异常,会掩盖原始异常)。JDK 7引入的try-with-resources能自动调用close(),前提是资源类实现AutoCloseable接口(如FileInputStream、BufferedReader)。
立即学习“Java免费学习笔记(深入)”;
- 语法:
try (Resource res = new Resource()) { ... },括号内声明的资源会在try结束时自动关闭 - 即使
try块中抛出异常,资源仍会被关闭;若close()也抛异常,它会被抑制(可通过getSuppressed()获取) - 多个资源用分号隔开,关闭顺序与声明顺序相反
常见误区与实用建议
写try-catch容易陷入“为了捕获而捕获”的陷阱。真正有效的异常处理,要服务于业务逻辑的健壮性和可维护性。
- 不要空
catch(即catch(Exception e) {}),这等于静默吞掉错误,会让问题难以定位 - 捕获具体异常类型,比笼统的
Exception更利于区分场景和做差异化处理 - 在
catch中至少记录异常信息(如用logger.error("读取配置失败", e)),必要时给用户友好提示(如“文件不存在,请检查路径”) - 自定义异常时,继承
Exception(检查型)或RuntimeException(非检查型),根据是否强制调用方处理来决定










