异常就是在程序运行时出现错误通知调用者的一种机制,运行时表示的是程序已经编译通过生成class文件,再由JVM执行的时候。
异常中的基本概念:
错误代码是客观存在的,所以当出现问题的时候要及时通知调用者,主要有两种方式:
LBYL:Look Before You Leap. 在操作之前做充分的准备
EAFP:It’s Easier to Ask Forgiveness than Permission. 事后获得原谅比事前获得许可更容易
防御式编程:
防御式编程就是我们先执行代码,碰到异常再解决,其实它的核心思想就是EAFP。
异常的基本用法:
捕获异常:
基本语法:
try{
//可能产生异常的代码
}
//捕获异常(非必须存在也可以有多个)
catch(异常类型 异常对象){
//Exception是所有异常类型的父类
//我们可以利用Exception捕获所有异常
//这里可以自己写碰这种异常我们想要给出什么方式的提示
System.out.println(“出现“异常类型”类型的异常!”);
//也可以直接利用系统写好的
异常对象.printStackTrace();
}
//善后工作(非必须存在)
finally{
//无论前面的代码有没有问题finally部分的代码都会执行
//一般将资源关闭、文件关闭、数据库连接关闭等操作放在这个部分
}
当出现异常但是我们没有catch或者没有合适对应的catch时,就会沿着调用栈向上传递,到方法的调用者,最终到JVM来解决,到JVM时的效果就是我们之前没有用try…catch时的样子。
若try、catch以及finally都有return时,finally的return就会覆盖try和catch的。
异常处理的存在可以保证无论是否有异常,正确的代码一定会执行!
异常处理的流程:
1、程序先执行try中的代码
2、如果try中的代码出现异常,就会结束try中的代码,看catch中的异常类型是否匹配
3、如果找到匹配的异常类型,就会执行catch中的代码
4、如果没有找到匹配的异常类型就会向上传递到上层调用者
5、无论是否找到匹配的异常类型,finally中的代码都会被执行到(在该方法结束之前执行)
6、如果上层调用者也没有处理异常,就继续向上传递
7、一直到主方法也没有合适的代码处理异常 ,就会交给JVM处理,此时程序就会异常终止
抛出异常:
用在方法内部,手动抛出异常,人工产生一个异常对象。
除了Java内置的类会抛出异常,我们也可以手动抛出异常,使用throw关键字来完成这个操作。这个操作通常搭配自定义异常来进行。
异常说明:
用在方发声明,表示该方法有可能出现异常,并且出现异常后不处理,向上抛出。
我们在处理异常的时候,通常希望知道这段代码哪里会出现异常,就可以使用throws关键字,给可能出现异常的方法进行标注,从而提醒调用者。也是搭配自定义异常来进行。
抛出异常和异常说明我们用一段模拟用户登陆的代码演示一下:
//用户登录过程中可能会出现两种异常
//用户名错误
//Exception是所有异常的父类
//所以我们自定义异常的时候也可以利用extends关键字继承父类
class userNameError extends Exception{
//构造方法
public userNameError(String warning) {
super(warning);
}
}
//密码错误
//继承父类Exception
class passWordError extends Exception{
//构造方法
public passWordError(String warning) {
super(warning);
}
}
public class login {
//登录方法(有可能产生异常)
//利用throws关键字标注方法
public static void userLogin(String userName , String name, String passWord ,String num)throws userNameError,passWordError{
if(!name.equals(userName))
{
//当用户名错误的时候抛出异常
//手动创建一个异常对象
throw new userNameError("用户名错误");
}
if(!num.equals(passWord))
{
//当密码错误时抛出异常
//手动创建一个异常对象
throw new passWordError("密码错误");
}
System.out.println("登陆成功!");
}
//主方法
public static void main(String[] args) {
String name="xiaoli";
String num="010102";
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName=scanner.next();
System.out.println("请输入密码:");
String passWord = scanner.next();
try {
//登录时可能出现异常放在try里
userLogin(userName, name, passWord, num);
}
//若是密码错误则调用我们自定义的密码错误异常解决
catch (passWordError passWordError) {
passWordError.printStackTrace();
}
//若是用户名错误则调用我们自定义的用户名错误异常解决
catch (userNameError userNameError) {
userNameError.printStackTrace();
}
}
}
异常体系:
非受查异常:程序可以不用显示处理该异常(Error类和RuntimeException及其子类)
受查异常:程序必须try…catch或者throws向上抛出
顶层类Throwable派生出两个子类Error和Exception。
Error表示java运行时内部错误或资源耗尽错误,出现这种内部错误程序只能终止。一般我们常见的Error就是栈溢出(StackOverFlowError)和内存溢出(OutofMemoryError)。
其中Exception也派生出了四个子类,其中RuntimeException以及其子类是非受查异常。