在Java中,将程序执行过程中发生的不正常行为称为异常。
我们一般常见的异常有:ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException,CloneNotSupportedException等等
异常种类繁多,为了对不同异常或者错误进行很好的分类管理,我们将异常分为
异常的处理
事前防御型:在操作之前就做充分的检查
一般通过if等语句提前进行判断
事后认错型:先操作, 遇到问题再处理
一般通过try—catch来进行判断
异常的抛出
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者
public static int getElement(int[] array,int index){
if(null==array){
throw new NullPointerException("传递数组为null");
}
if(index<0||index>=array.length ){
throw new ArrayIndexOutOfBoundsException("数组下标越界");
}
return array[index];
}
【注意事项】
1. throw必须写在方法体内部
2. 抛出的对象必须是Exception 或者 Exception 的子类对象
3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5. 异常一旦抛出,其后的代码就不会执行
异常声明throws
处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛
给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。
语法格式:
修饰符 返回值类型 方法名(参数列表)throws 异常类型1,异常类型2...{
}
public void OpenConfig(String filename)throws IOException,FileNotFoundException{
if(filename.endsWith(".ini")){
throw new IOException("文件不是.ini文件");
}
if(filename.equals("config.ini")){
throw new FileNotFoundException("配置文件名字不对");
}
}
【注意事项】
1. throws必须跟在方法的参数列表之后
2. 声明的异常必须是 Exception 或者 Exception 的子类
3. 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型
具有父子关系,直接声明父类即可。
4. 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出
try-catch捕获并处理
throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行
处理,就需要try-catch。
public static void main2(String[] args) {
int[] arr = {1, 2, 3};
int[] array=null;
try {
System.out.println("before");
System.out.println(arr[100]);
System.out.println("after");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("这是个数组下标越界异常");
e.printStackTrace();
} catch (NullPointerException e) {
System.out.println("这是个空指针异常");
e.printStackTrace();
}
System.out.println("after try catch");
}
【注意事项】
1. try块内抛出异常位置之后的代码将不会被执行
2. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到
JVM收到后中断程序----异常是按照类型来捕获的
3. try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获
4. 可以通过一个catch捕获所有的异常,即多个异常,一次捕获(不推荐)
finally
public static void main(String[] args) {
try{
int[] arr = {1,2,3};
arr[100] = 10;
arr[0] = 10;
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}finally {
System.out.println("finally中的代码一定会执行");
}
System.out.println("如果没有抛出异常,或者异常被处理了,try-catch后的代码也会执行");
}
注意:finally中的代码一定会执行的,一般在fifinally中进行一些资源清理的扫尾工作
面试题:
1. throw 和 throws 的区别?
1.作用不同: throw用于程序员自行产生并抛出异常, throws 用于声明该方法内抛出了异常;
2.使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws 必须跟在方法参数列表的后面,不能单独使用;
3.内容不同: throw抛出一个异常对象,且只能是一个; throws 后面跟异常类,且可以跟多个异常类;
4.如果异常对象是非 RuntimeException则需要在方法申明时加上该异常的抛出 即需要加上 throws 语句 或者 在方法体内 try catch 处理该异常,否则编译报错