一、异常:运行时抛出的程序错误
运行时指的是程序已经编译通过得到class文件,再由JVM执行时发生错误。
(javac 源文件 -> *.java -> *.class 编译过程)
1.除零异常
2.空指针异常
3.数组下标越界
二、
避免异常的两种方式:
LBYL:在操作之前就做了充分检查
EAFP:先操作,遇到错误再解决
异常的基本语法:(模拟王者登录游戏的执行过程)
//模拟王者登录游戏的执行过程
try {
//存放所有可能出现异常的代码
login();
loadGame();
chooseHero();
biubiubiu();
}
//catch 捕获相应的异常 {}内是出现相应异常的处理方式
catch (登陆异常){}
catch (载入游戏异常){}
catch (选取英雄异常){}
catch (正常游戏时出现的异常){}
finally{
//不是强制书写
//无论是否发生异常,都会执行finally代码块,一般执行资源的释放
//关闭资源的处理
}
1.使用try..catch..处理异常
将可能会报错的代码放入try中,并用catch捕获,当出现异常时不影响正常代码。
2.多个catch块
有多个异常就写多个catch。
3.使用异常的父类Exception来捕获异常(当程序出现较多异常,且不清楚是何种异常)
可以接受所有异常对象,都可以向上转型为Exception对象。
- 不推荐,不能排查问题
4.关于异常的错误输出
在Java中,一切皆对象,空指针,数组越界,Exception -> 都是异常,类产生异常时,JVM会构造一个相应的(相应的异常类)异常传递给程序。
5.关于finally代码块 - 无论是否产生异常,都会执行的代码块!
关于异常的返回值问题
一旦finally中带了返回值,相当于try和catch的返回值失效。
但是一般finally中不推荐写返回值。
6.关于异常的调用链
异常会随着调用链不断传递,直到被捕获异常并处理为止,若调用过程都没有处理异常,最终异常抛到JVM,程序就终止。
7.JDK7新增的自动关闭接口
一旦一个类实现了AutoCloseable接口,就表示该类具备了自动关闭的能力–声明在try代码块中会自动调用close方法。
8.—组关键字
throws:用在方法声明上,明确表示该方法有可能会产生该异常,但是不处理此异常,抛回给调用者处理。
throw:用在方法内部,人为产生异常对象并抛出。
三、异常体系结构
Error:指的是程序的内部错误,这种错误我们程序员无法捕获处理,一旦发生Error错误,程序只能告知用户出现错误,程序直接退出。
StackOverflowError:栈溢出Error -一般发生在递归调用链太深,递归没有出口
OutOfMemoryError:堆溢出Error
Java的异常体系分为两大类
1.非受查异常∶左图中蓝色方框以及其子类都属于非受查异常。所有的非受查异常不强制程序使用try catch块处理。Error以及RuntimeException(运行时异常,空指针,类型转换,数组越界)及其子类都是非受查异常
2.受查异常∶左图中红色方框以及其子类都属于受查异常,除了非受查异常外都是受查异常,必须显示使用try。。catch。。异常处理,或者throws抛出。除了Error和RuntimeExcpetion以及其子类的其他异常都是受查异常,必须显示处理。
3.自定义异常类∶程序开发中,一定会有一些错误是和具体的业务相关的,这种错误JDK是不可能提供相应的异常类,此时我们就需要继承已有的异类,产生自定义的异常类,若需要用户强制进行异常处理,继承Exception父类–受查异常若不需要用户显示处理异常,继承RuntimeException父类–非受查异常
四、【写一个有关登录异常处理的代码】
package object_oriented.exception;
import java.util.Scanner;
public class Login {
public static String USER="浩民";
public static String PASSWORD="123456";
public static void main(String[] args) {
try {
login();
System.out.println("登陆成功!!");
}catch (UserNameException e){
e.printStackTrace();
}catch (PasswordException e){
e.printStackTrace();
}
}
//throws 用在方法声明上,明确表示该方法可能会产生异常,但是不处理该异常,抛给调用者处理
private static void login() throws UserNameException{
Scanner scanner=new Scanner(System.in);
System.out.println("请输入用户名:");
String user=scanner.next();
System.out.println("请输入用户名密码:");
String password=scanner.next();
if(!USER.equals(user)){
//throw 用在方法内部,人为产生异常对象并抛出
throw new UserNameException("用户名错误!");
}
if(!PASSWORD.equals(password)){
throw new PasswordException("用户名密码错误!");
}
}
}
//用户名异常
class UserNameException extends Exception{
public UserNameException(String msg){
super(msg);
}
}
//用户名密码异常
class PasswordException extends RuntimeException{
public PasswordException(String msg){
super(msg);
}
}