****Java异常处理****
异常:程序中出现错误导致中断了正常的指令流。
编译错误逻辑错误都不是异常,异常是可以正常运行的程序在运行中可能发生的错误。没有异常处理的代码可能非正常结束出现严重的问题
常见的异常比如:
数组越界 (操作数超出范围)整数除0 网络中断 要打开的文件不存在
超出了某次资源限制如内存不够等
如果用if-else作为处理异常的方法的话,必须要仔细考虑可能出现的所有的错误类型以及对应的处理措施。增加了代码的复杂性,可读性变差。
If(a==0){输出错误信息}
Else 计算出发运算
Java try-catch语句处理错误:
异常的处理使得程序可以发现异常并处理异常,正常退出程序
try{
程序代码
}catch(异常类型1 异常的变量名1){
程序代码
}catch(异常类型2 异常的变量名2){
程序代码
}finally{
程序代码
}
与传统if-else的异常处理方式相比的优点:
1、 把错误代码从常规代码中分离出来
2、 把错误传播给调用堆栈
3、 系统提供对一些难以预料的错误的捕获和处理
4、 将错误类型分类
5、 克服了传统方法错误信息有限的问题
Java遇到异常有两种方式try-catch捕获并处理异常,一个try可以匹配多个catch;throw exception抛出异常
Try-catch-finally:
try{
程序代码
}catch(异常类型1 异常的变量名1){
程序代码
}catch(异常类型2 异常的变量名2){
程序代码
}finally{
程序代码
}
还是这个结构,try里的程序代码执行的时候如果出现异常就会抛出给外面,看紧接着的catch们有没有可以匹配的,匹配上的就进行对应catch的异常处理,匹配不上的就一层层回找,直到main函数如果还没有进行处理,就调用相关函数输出错误信息(就是常见的那种红字);
Finally中的代码是无论如何都会执行的代码,不管有没有异常什么异常有没有匹配,都要执行这部分代码。所以有非常重要的比如释放内存等,为防止在异常出现后不能继续执行应放在finally里
注意:
1、try catch finally不能单独用,以三种组合形式出现:try-catch-finally try-catch try-finally
2、finally跟声明常量的那个final没有关系
3、多个catch块的时候,最多会和其中一个匹配,其他的就不再执行
4、try catch finally三个部分的作用域各自独立
5、如果把一个异常类和其子类都放在catch里,那么应该把子类放在前面,否则永远到不了子类
举个例子:
try{
String[] A={"1","2"};
A[10]="77";
int a = 10/0;
System.out.println("Another");
}catch(ArithmeticException e){
System.out.println("异常是:"+e.getMessage());
}
catch(IndexOutOfBoundsException e){
System.out.println("异常是:"+e.getMessage());
}
输出:
异常是:10
//后面的一个异常和一个输出语句均没有执行
Throws声明异常和抛出异常
Throws在方法声明的时候说明该方法会抛出的各种异常,并说明该方法会抛出异常但不会处理异常
//声明异常:一个方法不处理他产生的异常,而是沿着调用层次向上传递,由调用他的方法来处理这些异常
声明异常的方法:
<访问权限修饰符><返回值类型><方法名>(参数列表) throws 异常列表{}
比如:
public void test(int a) throws MyException{}
关键词throws后面是该方法可能产生但不处理的异常类型,之间用,隔开
此时这中异常交由调用该方法的方法处理,或者交由系统处理,如果直到main函数还不能处理,程序就要异常终止了
举个例子:
public int compute(int x) throws
ArithmeticException e)
{ return z=100/x;}
public method1()
{ int x;
try { x=System.in.read();
compute(x);}
catch(IOException ioe)
{ System.out.println(“read error”); }
catch(ArithmeticException e)
{ System.out.println(“devided by 0”); }
}```
虚拟机(系统)处理的异常
对于程序中必须由系统处理的异常,可以使用throws语句抛出异常交由系统处理
比如:
public class ThrowsTest1{
public static void main(String args[])throws IOException{
FileInputStream fis=new FileInputStream(“a3.txt”);
}
}
“`
上述代码会在异常时由系统抛出异常
也可在代码中用throw关键字显式的抛出异常:throw 异常对象
程序会在throw语句时立刻终止,转而寻找try-catch,所以紧跟throw后面的代码没有意义,不会执行
//注意throws 和throw的区别啊
Java定义的标准异常类:
按照编译时是否受检分为两类:
非受检异常(unchecked exception):只能在程序运行时被检测到,不能在编译时被检测到,如RuntimeException及其子类
受检异常(checked exception):编译时就能被检测
创建自己的异常类:
Java的Exception类:一般性程序故障,一般由用户代码或类库生成并抛出,Java程序需要对他们处理
Exception类的两个构造方法:
Public Exception();
Public Exception(String s);s一般是要抛出的错误信息
该类常用的方法:
Public String toString();一般返回描述当前异常类信息的字符串
Public void printStackTrace();一般是在屏幕上输出调用堆栈的轨迹,常见的红字报错就是这个
所以对异常对象e获取异常信息的方法有三种:
1. e.toString( );
2. e.getMessage( );
3. e.printStackTrace( );
不过输出的格式不一样
所以写自己的异常类的时候可以让自己的异常类继承自Exception类,那么很多方法就可以覆盖或者重载或者用super直接调用了,然后其他会抛出这类异常的方法只要声明了throws该类的类名,在异常的情况下throw抛出即可(或者处理)