目录
一、什么是异常
所谓异常指的就是程序在运行时出现错误时通知调用者的一种机制。
常见异常如下所示:
除0异常:
空指针异常:
数组越界异常:
防御式编程:
LBYL:在操作之前就做充分的检查
EAFP:先操作,遇到问题再处理
二、异常的基本用法
2.1基本语法
try{
//存放所有有可能出现的异常;
}[catch(捕获相应的异常)...[0...N]]{
//出现相应异常后处理方式
}[finally]{
//无论是否发生异常,都会执行finally代码块。一般进行资源的释放
//关闭资源处置
}
2.2处理异常
1.使用try...catch处理异常:
将可能出现报错的代码放在try中,并用catch进行捕获,当出现异常后,不影响异常代码段之后的正常代码。
2.多个catch块
3.使用异常的共同父类Exception来捕获异常:
当程序出现多种异常、且有的异常编程时也不太清楚时使用Exception,但是一般不推荐使用,一般明确知道会产生哪种异常,就捕获相应的异常即可,这样方便排查问题。
4.关于异常的错误输出
在Java中,一切皆对象,异常也是对象,上面写的空指针,数组越界,Exception->都是异常类,当产生错误时,JVM会构造一个相应的(相对应的异常类)异常对象传递给程序。
5.finally代码块的使用:
通过运行发现,无论异常是否产生,finally代码块中的内容一定会执行,那么我们将资源关闭等重要操作放在finally中,表示最后的善后工作。
关于异常的返回值问题:
一旦finally中带了返回值,相当于try和catch的返回值就失效了,无论是否有异常产生,finally一定会执行,因此会覆盖try和catch的返回值。所以在finally中不推荐写返回值,除非返回值和异常无关,默认返回值就可放在finally中。
6.关于异常的调用链
①当一个方法中产生异常,但却没有处理时,此异常就会抛给调用者
②当main方法没有处理异常时,异常会抛给JVM
异常会随着调用链不断向上传递,直到有一处捕获异常并处理为止。若调用过程都没有处理异常,最终会将异常抛到JVM,程序就终止了。
7.JDK7新增的自动关闭接口
一旦一个类实现了AutoCloseable接口,就表示该类具备了自动关闭的能力——声明在try代码块中会自动调用close方法:
8.一组关键字
throws:用在方法声明上,明确表示该方法有可能会产生异常,但是不处理此异常,抛回给调用者处理
throw:用在方法内部,表示人为产生异常对象并抛出
三、异常体系
Java内置的异常类之间的继承关系:
Error:指的是程序的内部错误,这种错误我们程序员无法捕获,一旦发生Error错误,程序只能告知用户出现错误,程序直接退出。
非受查异常:Java语言规范将派生于Error类或RuntimeException类的所有异常(例如空指针异常,数组越界异常,类型转换异常)称为非受查异常,不强制程序使用try catch块处理
受查异常:所有的其他异常称为受查异常,必须显示使用try catch块处理,或者throws抛出
四、自定义异常类
程序开发中,一定会有一些错误是和具体的业务相关的,这种错误JDK是不可能提供相应的异常类,此时我们就需要继承已有的异常类,产生自定义的异常类。
自定义用户登录异常:
public class Login {
private static final String NAME="daiqin";
private static final String PASSWORD="123456";
public static void main(String[] args) {
try{
Login();
}catch (UserNameException e){
e.printStackTrace();
}catch (PassWordException e){
e.printStackTrace();
}
}
public static void Login(){
Scanner scanner=new Scanner(System.in);
System.out.println("请输入用户名:");
String name= scanner.next();
System.out.println("请输入密码:");
String password= scanner.next();
if(!name.equals(NAME)){
throw new UserNameException("用户名错误!");
}
if(!password.equals(PASSWORD)){
throw new PassWordException("密码错误!");
}
}
//用户名异常
static class UserNameException extends RuntimeException{
public UserNameException(String msg){
super(msg);
}
}
//密码异常
static class PassWordException extends RuntimeException{
public PassWordException(String msg){
super(msg);
}
}
}