Java异常处理概念和处理机制
异常概念
什么是异常?
所谓异常是指在程序运行的过程中发生的一些不正常的事件。(如:除0溢出,数组下标越界,空引用等等)
异常导致的后果?
Java程序的执行过程中如出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息,并将其提交给java运行时系统,这个过程称为抛出异常,不处理的话会导致程序直接中断。
如何防止程序中断?
设计良好的程序应该在程序异常发生时提供处理这些异常的方法,使得程序不会因为异常的发生而阻断或产生不可预见的结果
异常分类
受查异常:Exception及其子类(不包括RuntimeException),是由代码控制能力之外的因素导致的运行时错误(比如:文件不存在,数据错误),这种异常必须要处理,否则通不过编译
非受查异常:Error和RuntimeException及其子类,RuntimeException一般代表编程错误,可以不用处理。
Java异常处理机制
Java的异常是通过两种机制来处理的
捕获:try-catch-finally
try{}语句块中放的是要检测的java代码,可能会抛出异常,也可能会正常执行。
catch(异常类型){}语句块是娄java运行时,系统接收到try块中所抛出的异常对象时,会寻找能处理这一异常的catch块来进行处理(可以有多个catch块)
finally{}语句块是无论是否有异常产生,在try语句块执行完成后都会执行语句块。一般用来释放资源。除非在之前执行了System.exit(0)直接结束系统。
可以使用try-catch,也可以使用try-finally
抛出:throw(抛出异常)/throws(声明方法可能要抛出的异常)
throw用于手动抛出异常。程序员可以在任意位置手动抛出异常。
throws用于在方法上标识要暴露的异常。抛出的异常交由调用者处理。
两者区别:
throw用在方法内,throw后加要抛出的异常对象
throws修饰在方法上,告诉调用者此方法可能会抛出异常,throws后面加可能要抛出的异常类名
常见异常:
非受查异常:RuntimeException
受查异常:IOException,SQLException,ClassNotFoundException
自定义异常
Java提供的异常体系不可能预见所有希望加以报告的错误
自定义异常必须从已有的异常类继承
对异常来说,最重要的部分就是它的类名,其次是异常信息
demo:
import java.util.Scanner; import java.util.InputMismatchException; public class ExceptionDemo{ public static void main(String[] args){ testDemo1();//try-catch-finally测试 testDemo2();//throw,throws测试 testDemo3();//自定义异常 } public static void testDemo1(){ System.out.println("请输入一个数字:"); Scanner input=new Scanner(System.in); double res = 0; try{ int number = input.nextInt(); res = (double)10/(double)number;//输入0时会报错 return;//也会执行finally } catch(InputMismatchException ex){ System.out.println("输入格式不正确,详细错误:"+ex.getMessage()); ex.printStackTrace();//打印详细错误堆栈信息 } catch(ArithmeticException ex){ System.out.println("输入数值非法,详细错误:"+ex.getMessage()); ex.printStackTrace();//打印详细错误堆栈信息 } catch(Exception ex){//所有异常 System.out.println("发生错误,详细错误:"+ex.getMessage()); ex.printStackTrace();//打印详细错误堆栈信息 } finally{ //最后要执行的操作 System.out.println("结果为:"+res); System.out.println("——————————————————————————"); } } public static void testDemo2(){ Bar bar=new Bar(); try{ bar.enter(12); } catch(IllegalArgumentException ex){ System.out.println("参数非法错误:"+ex.getMessage()); } catch(Exception ex){//处理其他受查异常 System.out.println("其他错误:"+ex.getMessage()); } System.out.println("执行结束"); System.out.println("——————————————————————————"); } public static void testDemo3(){ Bar bar=new Bar(); try{ bar.enter2(15); } catch(IllegalArgumentException ex){ System.out.println("参数非法错误:"+ex.getMessage()); } catch(AgeToLessException ex){ System.out.println("自定义异常:"+ex.getMessage()); } catch(Exception ex){//处理其他受查异常 System.out.println("其他错误:"+ex.getMessage()); } System.out.println("执行结束"); System.out.println("——————————————————————————"); } } //throw,throws demo class class Bar{ //声明可能要抛出异常 //受查异常必须要声明,非受查异常可以不声明(但最好声明方便调用者处理) public void enter(int age) throws Exception{ if(age < 18){ //throw new IllegalArgumentException("年龄不符合规定");//非受查异常 throw new Exception("年龄不符合规定");//受查异常,调用者必须处理或继续声明才能编译通过 } else{ System.out.println("欢迎光临"); } } public void enter2(int age) throws AgeToLessException{ if(age < 18){ //throw new IllegalArgumentException("年龄不符合规定");//非受查异常 throw new AgeToLessException("年龄不符合规定");//受查异常,调用者必须处理或继续声明才能编译通过 } else{ System.out.println("欢迎光临"); } } } //自定义异常,继承自Exception都是受查异常 //在处理和声明时,要明确处理,也可以声明为 Exception,因为Exception为其父类,范围更大 class AgeToLessException extends Exception{ private String message; //public AgeToLessException(){ //} public AgeToLessException(String message){ this.message = message; } public String getMessage(){ return message; } }
效果: