一、Throwable类有两个子类:
1、Error:编译和系统错误,不捕获。(必须修改程序)
eg:int[] arr = new int[999999999999];
2、Exception:要我们处理的异常。(将异常处理掉,可以继续执行程序)
eg:int a = 1/0;
二、Throwable类中的方法(三个方法都和异常的信息有关)
1、String getMessage() 对异常信息的详细描述
2、String toString() 对异常信息的简短描述
3、void printStackTrace() 将异常信息追踪到标准的错误流,JVM默认调用的方法
说明:从结果上来看第二个方法打印出来的信息要多于第一个方法,但为什么说第一个是详细描述呢?因为API文档上是这样描述的,对我们影响也不大,可以不去深究。 JVM默认是第三种方法。
三、异常分为编译异常和运行异常
1、编译异常:(个人简单理解:语法错误引起的)调用了抛出异常的方法,不进行处理导致编译失败。(处理办法try...catch)。
2、运行异常:(个人简单理解:程序在运行过程中出现不可以预知的错误)抛出的异常是RuntimeException类,或者是它的子类
四、运行异常的特点:
1、在程序运行过程中不确定的位置出现
2、不需要在方法上用 throws 声明
3、运行异常一旦发生程序立马终止(因为如果程序出现了异常后面的程序执行结果也会错误,没意义)
五、JVM(JAVA虚拟机在异常中的作用)
1、创建了异常对象(eg:new ArrayIndexOutBoundsException())
2、将异常的对象进行抛出,抛给方法的调用者。
3、如果调用者没有处理的话,最后将抛给JVM。
4、JVM收到异常后,将异常信息以红色字体输出在控制台,并结束程序。
注意:一旦异常被抛出了,后面的程序不再执行
六、throw关键字:
1、在方法的内部,用于抛出异常对象
2、throw后面,必须写new 异常对象,必须是Exception或其子类
package note.basics;
public class abnormal {
public static void main(String[] args) {
getMax();
}
public static void getMax() {
//new 的对象只要是Exception或其下子类都可以,这里随便举例一个
throw new ArrayIndexOutOfBoundsException("出异常了!!!");
}
}
//程序运行结果:
// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 出异常了!!!
// at note.basics.abnormal.getMax(abnormal.java:25)
// at note.basics.abnormal.main(abnormal.java:8)
//一般用于开发者能够预知的异常
七、throws(方法中声明异常关键字):
throws用在方法的声明上(方法的后面),标明此方法可能出现异常
throws后面必须写异常类的类名、
附加:throw和throws的区别:
1)一个是用在方法中,一个用在方法声明
2)一个后面只能跟一个异常对象,一个后面可以跟多个异常类的类名
public class abnormal1 {
public static void main(String[] args) {
getMax();
}
//可以只抛出一个异常
public static void getMax() throws ArrayIndexOutOfBoundsException{
//......
}
//可以抛出任意个数异常,用分号分割
public static void getMin() throws ArrayIndexOutOfBoundsException,IllegalAccessException{
//......
}
}
八、调用一个抛出异常(非运行时异常)的方法,调用者就必须处理不然编译出错。(runtimeException或者其子类都是运行时异常,运行时异常无法判断,所以调用者不需要处理)
处理方法一:继续用throws向上抛 处理方法二:try...catch...finally
格式:
try{
被检测的代码(可能出现异常的代码)
}catch(异常类的类名 变量){
异常处理方式
循环、判断、调用方法、变量
} finally{
无论程序是否出现异常,finally里面的代码都会执行(这里有一个特殊就是被调用的方法里面有System.exit(0),程序会直接结束,也就不会执行finally,不过一般不这么做,没什么意义) 必须要执行的代码(这里和io结合最好,因为不管程序执行结果怎么样,都要关闭流)
}
try检测到了有异常的发生,接受到一个异常的对象,将异常的对象抛出,抛给catch代码块,处理这个异常 catch捕获异常,并处理异常。完毕后,程序可以继续执行
下面用代码简单说明一下:
public class abnormal1 {
public static void main(String[] args) {
//主方法
}
//调用非Exception异常 没报错
public void aaa(){
getMax();
}
//调用Exception异常,处理方法一:用throws继续抛出
public void bbb() throws Exception{
getMin();
}
//调用Exception异常,处理方法二:用try...catch捕获
public void ccc(){
try {
getMin();
} catch (Exception e) {
e.printStackTrace();
}
}
//抛出非Exception异常
public static void getMax() throws ArrayIndexOutOfBoundsException{
//......
}
//抛出Exception异常
public static void getMin() throws Exception{
//......
}
}
九、可以一个try 多个 catch多个catch写在一起:
1、catch小括号里,写的是异常的类名+变量( eg:catch (Exception e){} )
2、有顺序概念
1)平级异常:抛出的异常类之间,没有继承关系,没有顺序
2)上下级关系的异常:先捕获下级,最下面捕获最高级
3)这里列举几个异常继承关系
NullPointerException extends RuntimeException
NoSuchElementException extends RuntimeException
NullPointerException extends RuntimeException
extends Exception
ArrayIndexOutOfBoundsException extends
IndexOutOfBoundsException extends RuntimeException
public class abnormal1 {
public static void main(String[] args) {
//这是正确的
try{
getMax(0);
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}catch(RuntimeException e){
e.printStackTrace();
}
//编译会出差,因为上面这个catch也能处理下面这个异常,下面这个catch不会被执行
try{
getMax(0);
}catch(RuntimeException e){
e.printStackTrace();
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
}
public static void getMax(int a) {
//例子中用到的两个异常的继承关系
//ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException extends RuntimeException
if(a == 0)
throw new RuntimeException();
else if(a == 1)
throw new ArrayIndexOutOfBoundsException();
}
}
十、继承后,在子类重写父类方法的时候,异常处理
父类的方法,如果抛出异常,子类重写后
1) 可以不抛异常
2) 也可以抛异常,但是如果子类要抛,抛出的异常不能大于父类的异常(大于,都指的是继承关系)
父类的方法,没有抛异常,子类重写后 也不能抛出异常,如果子类中调用了抛出异常的方法,别无选择,只能try...catch处理
十一、自定义异常:
1)继承Exception,或者继承RuntimeException
2)构造方法中,super将异常信息传递给父类