1.异常类型
错误类型
-
语法错误(syntax errors):没有遵循语言规则
-
运行错误(runtime errors):发生一个不可能执行的操作
-
逻辑错误(logic errors):没有按照预期的方案执行
运行时错误会作为异常抛出,如果异常没有被处理,程序会被非正常终止。Java作为面向对象的语言,异常也是对象。我们需要学会处理异常,让程序能够继续运行下去或者优雅地终止
常见异常:用户输入无效值、程序打开不存在的文件、网络中断、数值下标越界等
异常处理:当产生一个异常,正常的程序执行流程就会中断,异常处理提供给程序员处理运行异常的功能
异常类型
-
java.lang.Throwable是所有异常类的父类
-
异常的三种类型
- 系统错误(Error):描述系统内部的错误,由Java虚拟机抛出并在Error类中表述,这种错误很少发生,如果发生,除了通知用户以及尽量稳妥地结束程序,几乎什么都不能做
- 运行异常(RuntimeException):由RuntimeException描述,经常描述程序设计错误,比如错误的类型转换、访问一个越界数值或数值错误等,通常Java虚拟机抛出
- 异常(Exception):描述程序和外部环境引起的错误,这些错误能通过程序捕获或处理
-
免检异常:RuntimeException、Error以及他们的子类,为了避免过多使用try-catch语句块,Java不强制要求程序员编写捕获或声明免检异常的代码,一般它反映出程序设计上不可恢复的逻辑错误
-
必检异常:除RuntimeException、Error以及他们的子类外的所有异常,编译器要求程序员检查并处理它们
2.异常处理
try-throw-catch语句块
try{
Code to run;
A statement or a method that may throw an exception;
More code to run;
}catch(type ex){
Code to process the exception;
}
优点:异常能使方法抛出一个异常给它的调用者,并由调用者处理该异常,调用者的catch块处理该异常,将检测错误(由调用的方法完成)从处理错误(由调用方法完成)中分离
异常处理三个环节
-
声明异常:每个方法都必须说明它可能抛出的必检异常的类型
public void Method()throws Exception1,...,ExceptionN
-
抛出异常:检测一个错误的程序,可以创建一个异常的实例并抛出它
public void Method()throws Exception{ if(an error occurs){ throw new Exception; } }
-
捕获异常
- 异常处理器:处理异常的代码
- 捕获异常:寻找处理器的整个过程称为捕获异常,从第一个到最好一个逐个检测catch块,如果找到就执行当前的catch块语句,否则退出这个方法,把异常传递给调用这个方法的方法再查找异常处理器
-
注意:catch语句块中异常排列顺序非常重要,如果异常父类的catch语句块出现在异常子类catch语句块之前,会导致编译错误
finally
- 功能:当try语句块退出时,finally语句块总是要执行,不管异常是否抛出
- 通常用于I/O编程
自定义异常
继承java.lang.Exception类定义自己的异常类,然后声明产生异常的方法
链式异常
catch块可以重新抛出原始异常,有时候需要同原始异常一起抛出一个新异常,称为链式异常
断言
-
断言语句用于调试代码阶段
-
在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程序又需要调试,可以重新启用断言语句
- assert booleanExpression;
- assert booleanExpression:messageException;
- 如果表达式为true则断言为真,无行动,表达式为false,断言为假,抛出一个AssertionError对象,冒号后是一个表达式,通常用于断言失败后的提示信息
-
必须不依赖它们完成任何程序实际所需的行为,使用断言或者不使用断言不影响程序执行结果
-
断言运行方式:java -ea 类名
3.总结
异常处理优点:将错误处理代码从正常的程序设计认为中分离,可读性更好
异常处理缺点:异常处理需要初始化异常对象、调用栈返回、沿方法调用链查找异常处理器,因此需要更多的时间和资源
原则
- 如果能在方法内处理异常不需要抛出,即对于发生在个别方法中的简单错误最好做局部处理,无须抛出异常
- 如果需要调用者处理异常需要抛出
- 一个项目中,如果多个类发生的共同异常考虑自定义异常类
- 一般能用简单逻辑判断的不要使用异常
实际应用