Java 异常
程序在运行过程中出现的特殊情况
异常处理的必要性:任何程序都有可能出现大量的未知问题、错误;如果不对这些错误进行正确处理,则可能导致程序中断,造成不必要的损失。
异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中
Throwable的子类为Error和Exception,其中Error是JVM、硬件、执行逻辑错误,不能手动处理;而Exception是程序在运行和配置中产生的问题,可处理。而Exception下有很多子类,主要分为RuntimeException类和[CheckedException]类。这里[CheckedException]代指除RuntimeException类的类
这里列举几个常见的运行时异常
NullPointerException:空指针异常ArrayIndexOutOfBounds:数组越界异常ClassCastException:类型转换异常NumberFormatException:数字格式化异常ArithmeticException:算数异常
异常的产生
- 自动抛出异常:当程序运行时遇到不符合规范的代码或结果时,会产生异常
- 手动抛出异常:
throw new 异常类型("实际参数") - 产生异常结果:相当于遇到
System.exit(0)语句,导致程序异常而终止
异常的传递
按照方法的调用链反向传递,如果始终没有处理异常,最终会由JVM进行默认处理(打印栈跟踪信息)并中断程序。
异常处理
异常的处理非常重要,它使我们的程序在遇到错误时,能正确提醒我们哪里出错了,帮助我们快速解决问题。
一些常见的异常处理结构:多重catch,遵循从子到父的顺序,父类异常在最后
try{}catch{}try{}catch{}catch{}try{}catch{}finally{}try{}catch{}catch{}finally{}try{}finally{}
// 介绍每个代码块的具体作用
try{
// 可能出现异常的代码
} catch(异常类型 异常对象) {
// 1. 自定义
// 2. 异常对象.getMessage()
// 3. 异常对象.printStackTrace()
} finally {
// 无论发生什么异常都会执行的代码,常用于释放资源
}
这里有个问题:try{}、catch{}、finally{}中是否可以包含return语句?如果try{}里面有一个return语句,那么finally{}中的代码会不会执行?答案是可以的,也会执行finally{}中的代码。
DeBug也是常用的异常处理手段
声明异常
- 如果在一个方法体中抛出了异常,如何通知调用者?通过
throws关键字,声明异常 - 底层代码向上声明或抛出异常,最上层一定要处理异常,否则程序中断。
抛出异常
除了系统自动抛出异常外,有些问题需要程序员自行抛出异常
throw关键字,抛出异常throw 异常对象
自定义异常
需要继承
Exception或Exception的子类,代表特定问题
异常名称望文生义,可在发生特定问题时抛出对应的异常
常用构造方法
- 无参构造方法
- 带有
(String message)参数的构造方法
方法重写
带有异常声明的方法重写
- 方法名、参数列表、返回值类型必须和父类相同
- 子类的访问修饰符和父类相同或比父类范围更大
- 子类中的方法,不能抛出比父类更多、更宽的检查时异常。主要是子类重写的方法抛出的异常范围小于等于父类被重写方法抛出的异常