异常
异常的定义:就是程序出现了不正常的情况
Error:严重问题,不需要处理
Exception:称为异常类,它表示程序本身可以处理的问题
RuntimeException:在编译期是不检查的,出现问题后,需要我们回来修改代码
非 RuntimeException:编译期就必须处理的,否则程序不能通过编译,就更不能正常运行了
为什么要使用异常处理机制?
因为运行时异常处理在运行时不受检,可能会因为用户的不当操作而导致不同的异常类型,jvm会默认运行到异常的位置从而结束系统程序的运行,如果不进行异常的处理就会导致程序结束,对于用户来说直接会导致系统的崩溃。
代码执行时本身如果没有处理异常的语句,jvm会进行异常处理但是并不是很好因为会中断程序。//扩展—在编译生成的字节码中,每个方法都会有一个异常表。异常表的每一条都代表一个异常处理器。有from指针,to指针、target指针和锁捕获的异常类型构成。这下指针的值是字节码索引bci,用来定位字节码。from和to指针标示了异常处理器要监控的范围,即try代码块的内容。target指针则是catch代码块的起始位置。当发生异常时,jvm会从上至下遍历所有的数据,当触发异常的字节码索引在某个from-to范围内,jvm就会判断抛出异常的类型和该条要捕获的异常的类型匹配的时候,jvm的控制流就会转向该catch块的字节码。如果遍历完之后还没找到对应的类型,jvm就会沿着调用栈向上执行同样的操作。在最坏的情况下,jvm会遍历这个调用栈的每一个调用者。而对于finally块,jvm是把这个finally块的字节码复制到 try-catch块的所有正常退出,异常退出的出口那。
Try-Catch
try{
可能出现异常的语句
方法体语句
}catch(异常类名 变量名){
异常处理的代码
}
Throwable的成员变量
方法名 | 说明 |
---|---|
public String getMessage() | 返回此 throwable 的详细消息字符串 |
public String toString() | 返回此可抛出的简短描述 |
public void printStackTrace() | 把异常的错误信息输出在控制台 |
编译时异常与运行时异常的区别
Java 中的异常被分为两大类:编译时异常和运行时异常,也被称为受检异常和非受检异常
所有的 RuntimeException 类及其子类被称为运行时异常,其他的异常都是编译时异常
- 编译时异常:必须显示处理,否则程序就会发生错误,无法通过编译
- 运行时异常:无需显示处理,也可以和编译时异常一样处理
运行时异常处理的方法:
1.用try -catch语句进行处理,
2.用throws语句进行处理,将问题抛出给上游的人,因为在具体业务中每个人对同一种异常有不同的处理方法,能不能决定下游的人传递给你的数据,也不能决定上游的人处理你异常的方法,因此你最好提供的是建议(定义的异常)。
自定义异常
public class 异常类名 extends Exception {
无参构造
带参构造
}
当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常需要注意的是,唯一有用的就是类型名这个信息,所以我们不需要在异常类的设计上花费太多精力一个类要想成为异常类的一员,要么继承Exception,要么继承RuntimeException通常情况下,会直接继承自Exception类,给出无参和带参构造方法即可
throws与throw的区别
- throws的位置在声明方法的后面跟的是异常类名,throw在方法体内部,跟的是异常对象名。
- throws表示抛出异常由其上游进行处理,而throw表示抛出异常由其方法体内语句处理。
- throws表示出现异常的一种可能,并不一定会出现这种异常;throw表示一定出现了某种异常。
自定义异常
package yichang03;
//继承异常类
public class MyException extends Exception {
String message;
//构建无参和有参方法
public MyException(String message) {
System.out.println("有参构造方法的异常");
}
public MyException() {
System.out.println("无参构造方法的异常");
}
//构建Demo使用自定义异常
public class Demo extends MyException {
//构造方法
static int compare(int x,int y)throws MyException{
if (y<0){
System.out.println("y不能小于零");
}
return x/y;
}
//主函数
public static void main(String[] args) {
try{
//创建对象调用方法
int test=compare(5,2);
}catch(MyException e){
System.out.println(e.getMessage());
}catch (ArithmeticException e){
System.out.println("被除数不能为零");
}catch (Exception e){
System.out.println("其余错误");
}
}
}
.println(“被除数不能为零”);
}catch (Exception e){
System.out.println(“其余错误”);
}
}
}