异常:指的是程序在执行过程中出现非正常的情况,会导致JVM非正常停止
在Java等编程语言中,异常的本身是一个类,Java处理异常的方式是中断处理,异常不是语法上的错误。
异常的根类:Throwable,存在于lang包下,Throwable有两个子类(Exception和Error),Exception是程序的正常异常是可以解决的,而Error是严重的错误。
(异常):分为两类,一类是编译异常Exception(编译的时候程序出现的问题,这是小问题),另一类是运行期异常runTimeException(运行的过程中出现的问题),不管是编译异常还是运行期异常都会使得程序出现小问题,只要处理掉程序就可以继续执行。
错误:Error是程序中出现的比较大的问题,无法处理,需要直接更改源码;以下是一个内存溢出错误的例子,错误是必须修改源代码的;比如把分配数组的内存减少
![02fff14840c8e316279b9ab7f009e055.png](https://img-blog.csdnimg.cn/img_convert/02fff14840c8e316279b9ab7f009e055.png)
public class Demo01Exception {
public static void main(String[] args) {
int []arr=new int [1024*1024*1024];
}
}
//内存异常错误代码
编译期异常特例:SimpleDateFormat类中的parse 方法在编译就过程中就会出现问题,需要抛出异常才能使得程序继续运行
运行期异常特例:索引越界异常,在运行的时候才会发现问题(ArrayIndexOutOfBoundsException: 3)
![58f1a288e72b92656e75bfe943a0107a.png](https://img-blog.csdnimg.cn/img_convert/58f1a288e72b92656e75bfe943a0107a.png)
public class Demo01Exception {
public static void main(String[] args) {
int []arr={1,2,3};
System.out.println(arr[3]);
}
}//运行会产生数组索引越界异常代码;,异常可以通过抛出异常来使得程序继续运行
异常的产生和处理过程:
以数组越界异常为例子:
如数组int []arr ={1,2,3},当我访问arr[3],这个时候JVM就会检索出异常,因为这个数组最大的索引也就2,。
JVM这个时候做的事情:根据对应的异常创建一个异常对象,这个异常对象包含了异常产生的(内容,位置,原因),,然后JVM把异常抛出给调用这个异常方法的main()函数处理
这个时候main方法做的事情:
1.如果main方法中有处理异常的过程代码,那么就将异常处理,程序正常运行,如果没有就把这个异常交还给JVM处理
当异常再次交给JVM处理的时候,JVM接收异常并且把异常对象(位置,原因,内容)打印在控制台上,然后再中断处理(停止java程序)
异常的处理:
1.throw关键字:
作用:可以将异常抛出
使用的格式: throw new xxxException("异常产生的原因");//表明抛出的是一个什么异常
注意:throw 必须写个某个方法的内部
throw关键字后面new的一定是个Exception或者它的子类
throw关键字抛出指定的异常后,我们就必须处理这个异常
throw关键字创建的如果是runTimeException或者它的子类对象的话,我们可以不处理,交给JVM处理(如数组越界处理),说明了编译期异常一定要处理,运行期异常可以不处理(默认JVM处理)
![0ac29c7642f53aa19f5ed9deb66b8962.png](https://img-blog.csdnimg.cn/img_convert/0ac29c7642f53aa19f5ed9deb66b8962.png)
/*
throw关键字可以抛出指定方法中的异常
使用的格式:throw new xxxException("异常 产生的原因")
注意:
throw的关键字必须要写在方法的内部
throw关键字后边new的对象必须是个Exception或者它的子类
throw关键字抛出指定的异常对象,我们就必须处理这个异常(两种处理方法)
1.throw 后边创建的是RuntimeException或者它的子类对象我们可以不处理.交给JVM来处理(打印异常,中断程序)
2.throw后边创建的是编译异常我们就必须处理这个异常,要么throw要么try...catch;
*/
public class Demo02Throw {
/*
定义一个方法,获取数组索引的元素
在工作中我们必须对方法中传递的参数进行合法性校验,如果参数不合法就必须使用抛出异常的方式告诉调用者调用的参数有问题
*/
public static void main(String[] args) {
int []arr=new int[3];
int e=getElement(arr,10);
System.out.println(e);
}
public static int getElement(int []arr,int Index){
/*
我们可以对传递过来的参数数组进行合法性的校验
如果arr的值是null
那么就可以用空指针异常告知调用者传递的数组的值是null
*/
if (arr==null){
throw new NullPointerException("传递的数组的值是空");//我们没有给处理的方法所以交给JVM处理空指针异常是运行期的异常
}
if (Index<0||Index>arr.length-1){
throw new IndexOutOfBoundsException("指针越界异常");//指针越界抛出异常
}
int s=arr[Index];
return s;
}
}
可以看到,当任意一个if条件成立,抛出异常后,后面的代码不再执行。使用throw关键字抛出异常后,如果在方法内部没有自行处理的方法的话,就会将异常抛出到调用方法的函数中,上面的例子就是异常没有处理,所以异常被抛出到main()中,main()中也没有处理异常的方法,所以最终就交付到JVM让JVM默认处理,当异常再次交给JVM处理的时候,JVM接收异常并且把异常对象(位置,原因,内容)打印在控制台上,然后再中断处理(停止java程序)
2.throws关键字
throws关键字是异常处理的第一种方式,交给别人处理
作用:
当个方法内部抛出异常对象的时候,那么我们就必须处理这个异常
可以使用throw关键字处理异常对象,会把异常对象声明抛出给方法的调用者(交给别人处理),如果别人也没有处理那么就默认最后交给JVM出库
使用方法:
在方法声明的时候使用
修饰符 返回值类型 方法名字(参数列表) throws XXXException{
throw new XXXException("产生原因");
}
注意事项:
1.throws关键字必须写在方法的声明处
2.throws关键字后边声明的异常必须是Exception或者是它的子类
3.如果抛出多个异常,那么就需要声明多个异常。方法内部如果抛出多个异常对象有子父类关系,那么直接声明父类异常就行、
4.如果调用了一个声明异常的方法,那么调用者要么就继续用throws声明抛出(自己处理不了还调用,那么就再声明再抛出给别人),最终没人处理的话就默认交给JVM处理。要么就是第二中,自己处理,用try.........catch的方式自定义处理方式;
未完待续