1. 什么是异常?
异常就是Java程序在运行过程中出现的错误。如程序要打开一个不存的文件、网络连接中断、操作数组越界、装载一个不存在的类等。2. Throwable类
2.1 java将所有的错误封装成为一个对象,其根本父类为Throwable。2.2 两个直接的子类:
2.2.1 Error:指的是底层的、低级的、不可恢复的严重错误。此时程序一定会退出。
因为已经失去了运行所必须的物理环境,一般不编译特定的代码进行处理
2.2.2 Exception:要用针对性的处理方式进行处理
2.2.2.1 RunntimeException: 运行时异常,可以不进行处理。
2.2.2.2 非RunntimeException: 这类异常要进行处理,要么捕获,要么声明。否则变异无法通过。
2.2.3 异常类的常用方法:
2.2.3.1 getMessage() 获取异常信息,返回字符串。
2.2.3.2 toString() 获取异常类名和异常信息,返回字符串。
2.2.3.3 printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。
2.2.3.4 printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。
3. 处理异常的两种方式:
3.1 第一种方式: 捕获
3.1.1 后面可以跟多个catch块,即多个异常对象,但这些异常对象子类应该在上面。
因为如果异常的父类在上面,在程序出异常时,能被子异常类处理的异常就被放在它上面的父异常类处理了,
子异常类永远也执行不到。
try{
可能出现异常的代码
}catch(异常类型,变量){
异常处理方式
}
3.1.2 finally是一定执行的块,一般用来关闭资源。
try{
可能出现异常的代码
}catch(异常类型,变量){
异常处理方式
}finally{
一定会执行的语句
}
3.1.3 这种方式并不能捕获异常,因为没有catch进行处理,当try中出现异常时,是会直接抛给调用者去处理,
前提是运行时异常,否则编译不能通过。
try{
可能出现异常的代码
}finally{
一定会执行的语句
}
3.2 第二种方式: 声明
在函数内部直接将异常抛出,并在函数上声明这个异常,将异常抛给调用者处理
int getChuFa()throws ArithmeticException{
if(b = 0) // 除数为0了。
throw new ArithmeticException;
return a / b;
}
3.3 Throw与Throws的区别
3.3.1 Throw 用在函数内部,在函数内部抛出异常,后面跟的是对象。
3.3.2 Throws 用在函数声明上,后面跟的是异常类,并且可以跟多个异常类,中间用逗号分隔。
4. 自定义异常类
4.1 自定义类必须是继承Exception体系的类
因为异常类和异常对象都具有可抛性,这个可抛性是Exception这个体系中独有的特点,所有
自定义的异常类要继承与此体系。
也只有这个体系中的类才可以被throw和throws所操作。
4.2 如果不想对自定义的异常进行处理,可以让自定义的异常类继承RuntimeException类。
/*
要求:自己定义一个异常:除数不能为负数的异常。
*/
class ExceptionTest{
public static void main(String[] args){
Test t = new Test(8,-2);
try{
int i = t.getChuFa();
System.out.println(i);
}catch(ArithmeticException ae){
ae.toString();
}catch(FuShuException fs){
fs.toString();
fs.getMessage();
fs.printStackTrace();
System.out.println(fs.getI());
}
System.out.println("这里开始执行了!!!");
}
}
class Test{
int a;
int b;
Test(int a, int b){
this.a = a;
this.b = b;
}
// 采用了第二中方式,将异常抛出并作出声明。
int getChuFa()throws ArithmeticException,FuShuException{
if(b < 0)
throw new FuShuException("除数为负数了。",b);
return a / b;
}
}
//自定义的异常类。
class FuShuException extends Exception{
private int i;
FuShuException(String mess,int i){
super(mess);
this.i = i;
}
public int getI(){
return i;
}
}
5. 异常在字符类中的体现
4.1 子类在覆盖父类的方法时,如果父类的方法抛出异常,那么子类只能抛出父类的所抛的异常或子类。
4.2 如果父类抛出多个异常,那么子类在覆盖父类此方法时只能抛出父类异常的子集。
4.3 如果父类或者接口中的方法没有异常抛出,那么子类在复写此方法时,也不可以抛出异常,只能try。
6. finally和try中return的执行顺序
6.1 finally块是一定会执行的,除非程序停止运行,退出虚拟机。System.exit(0);
6.2 finally语句是在return语句之后,跳转到上一级程序之前执行(即return语句中间执行)
/*
* 用代码证明,在try中写了return,后面又写了finally,是先执行return还是先执行fianlly?
*/
public class ExceptionTest {
public static void main(String[] args) {
System.out.println(method());
}
static int method(){
int i = 1;
try{
return ++i;
}finally{
i = 5;
System.out.println("finally开始执行了!");
}
}
}
打印结果为:
finally开始执行了!
2