异常
![]()
程序在运行过程中发生由于外部问题导致的程序异常事件,发生的异常会中断程序的运行。(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。在java中异常不是错误。
认识Exception
Exception 位于java.lang包下,他是一种顶级接口,继承与Throwable类,Exception类及其子类都是Throwable的组成条件。是程序出现的合理情况。
什么是Throwable
Throwable是java中所有错误(errors)和异常(exception)的父类。只有继承于Throwable的类或者子类才能被抛出,还有一种方式是带有java中的 @throw 注解类也可以抛出。
除了RuntimeException 和其子类,以及error和其子类,其它的所有的异常都是 checkedException。
归类
![]()
常用方法
//返回抛出异常的常用信息
public string getMessage();
public string getLocalizedMessage();
//返回异常发生的简要描述
public public String toString()Ҕ
//打印信息到标准输出流上
public void printStackTrace();
public void printStackTrace(PrintStream s);
public void printStackTrace(PrintWriter s)
// 记录栈帧的当前状态
public synchronized Throwable fillInStackTrace();
此外,应为Throwable父类也是Object,所以常用的方法还有继承其父类的getClass() 和getName()
常见的Exception
Exception 用两种常见的异常:
RuntineException
CheckedException
这两种异常都应该捕获。
常见的 RuntimeException
![]()
UncheckedException
![]()
与Exception有关的关键字
throws whrow try finally catch
throws和throw
在java中,异常也就是一个对象,它能够被程序员自定义抛出或者应用程序抛出,必须借助于throws和throw语句来定义抛出异常。
例如:
static void cacheException() throws Exception{
throw new Exception();
}
throw 在方法体内,表示抛出异常,由方法体内的语句处理。throws在方法声明后面,表示抛出异常,由方法的调用者来处理。
throws主要声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。
try/cath 表示对某一段代码可能抛出段异常进行捕获,
static void cacheException(){
try {
System.out.println("1");
}catch (Exception e){
e.printStackTrace();
}
}
try/finally 表示一段代码不管执行情况如何都会执行finally块的代码
static void cacheException(){
for (int i = 0; i < 5; i++) {
System.out.println("enter: i=" + i);
try {
System.out.println("execute: i=" + i);
continue;
} finally {
System.out.println("leave: i=" + i);
}
}
}
Error
Error是程序无法处理的错误,表示运行应用中比较严重段问题。大多数错误与代码编写者执行段操作无关,而是代码运行时jvm(java虚拟机)出现的问题。这些错误是不可检测的,因为他们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况,比如OutOfMemoryEeeor和 StackOverflowError。
异常的出现会有几种情况,这里需要先介绍一下java内存模型
![]()
其中包括两部分,由所有线程共享的数据区和线程隔离的数据区组成,在上面的java内存模型中,只有程序计算器是不会发生OutOfMemoryError 情况段区域,程序计数器控制着计算机指令的分支、循环、跳转、异常处理和线程恢复,并且每个程序计数器是每个线程私有的。
线程私有:表示段就是各个线程之间互补影响,独立存储的内存区域。
如果应用程序执行段是java方法,这个计数器记录的就是虚拟机字节码指令的地址,如果正在执行的是Native方法,这个计数器的值则为空。
除了程序计数器以外,其他区域都有可发生OutOfMemoryError。
- 虚拟机栈:如果线程请求的栈深度大于虚拟机栈所允许段深度,将会出现StackOverflowError。如果虚拟机动态扩展无法申请到足够段内存,将出现OutOfMemoryError。
- 本地方法栈和虚拟机栈一样
- 堆:java堆可以处于物理上不连续,逻辑上连续,就像我们段磁盘空间一样,如果堆中没有内存完成时例分配,并且堆无法扩展时,将会抛出StackOverflowError。
- 方法区:方法区无法满足内存分配需求时,将抛出OutOfMemoryError.