我们编写的程序都会经过编译、运行这两个阶段,在这两个阶段都会出现异常。Java将这两个阶段的异常分别称为Checked异常和Runtime异常:
强制处理
图片中 RuntimeException
类的子类全部为 Runtime异常
,而继承至 Exception
的其他子类为 checked异常
图片中还有另一个分支 Error
, Error
错误与虚拟机相关( OutOfMemoryError
之类的),大部分的 Error
错误会导致程序或JVM处于非正常、不可恢复的状态,因此没有捕获的必要。
当程序运行期间出现了意外情况,系统会自动生成一个Exception对象来通过程序。从而将“业务实现代码”和“错误处理代码”分离,提高程序的可读性
Java的异常处理机制主要依赖于try、catch、finally、throw、throws五个关键字。
把程序的业务实现代码放在try块中,异常处理逻辑放在catch块中进行处理。
抛出异常:执行try块里的业务实现代码时出现异常,系统将自动生成一个异常对象,并将其提交给运行时环境
捕获异常:当运行时环境接收到异常对象时,会 自上而下
依次判断该异常对象是否是catch块后异常类或其子类的实例。如果找到 合适
的catch块,则把该异常对象交给catch块处理(在程序进入catch块时,赋值于catch块的形参)。否则,将终止运行时环境并退出程序。
Java的垃圾回收机制只能回收堆内存中的对象所占用的资源,不会回收任何 物理资源
物理资源像数据库连接、网络连接、IO操作等都需要显示回收,显示回收的两种方式为添加 finally
块或使用自动关闭资源的try语句
try、catch
块中调用了退出虚拟机的方法( System.exit(0)
),否则无论 try、catch
块中出现什么情况,异常处理的 finally
块总会被执行 finally
块中使用了 return
或 throw
语句,方法最终将得到 finally
块中的 return
或 throw
的结果,无论 try、catch
块中是否有 return
或 throw
语句 //()中是可关闭的资源的声明 //这些资源类必须实现AutoCloseable或Closeable接口,从而实现close()方法 try(BufferReader reader=new BufferReader(...)){ //do something } 复制代码
//Closeable是AutoCloseable的子接口,只包含close一个方法 //区别是Closeable中的close抛出IOException异常,而AutoCloseable抛出Exception异常 public interface Closeable extends AutoCloseable { public void close() throws IOException; } 复制代码
当前方法不知道如何处理该类型的异常,应该将异常向上级调用者抛出。直到main方法也无法处理时,该异常将交由jvm处理,jvm的处理方式是——打印异常的 StackTrace
信息,并中止程序运行。
有一类异常大多数是根据业务需求来决定的,由于与业务需求不符合而产生的异常,必须由开发人员来决定抛出
throw new IllegalArgumentException("非法参数"); 复制代码