Day18 异常
本章任务
1.异常的分类
2.异常的传递
3.异常的处理
4.try{} catch{} finally{}
5.带有异常声明的方法重写
一、异常的概念
在程序执行过程出现特殊情况叫做异常
异常处理的必要性:任何程序都可能存在大量的未知问题、错误;如果不对这些问题进行处理,则可能导致程序的中断、造成不必要的损失。
二、 异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中
|-Error:JVM、硬件、执行逻辑错误,不能手动处理
|-Exception:程序在运行或配置中产生的问题,可处理
|-RuntimeException :运行时异常,可处理,可不处理
|-CheckedException :检查异常,必须处理
运行时异常
运行时异常:(RuntimeException)在编译过程不会发现(没有语法错误),但是在执行程序程中,由于重大的逻辑错误导致的程序中断
常见的运行时异常
NullPointerException 空指针异常(一个对象没有初始化调用方法)
IndexOutOfBoundsException 下标越界异常
ClassCastException 类型转换异常(对象类型转换时)
NumberFormatException 数字格式异常
ArithmeticException 算术异常
非运行时异常
非运行时异常:编译异常或检查异常,在程序设计过程中,编译时就会被发现,但是执行时可能发生也可能不发生的异常,为了程序不报错可以执行,那么这一类异常必须进行相应的处理
三、异常的处理方式
抛出异常:throws和throw
1.throw关键字:抛出异常
语法:
//使用格式:throw 异常对象; throw new Exception();
2.throws关键字:上抛异常(手动抛出异常)
上抛异常,将异常抛到方法的签名后,表示提示方法的调用者此方法具有异常没有处理,你若想使用我,需要对此异常进行处理。
语法:
public static void fun()throws 异常A或异常A的父类{ throw new 异常A; }
捕获异常:try…catch…finally语句
语法:
try{
//功能代码
}catch(异常类型1 异常引用1){
//异常处理代码1
}catch(异常类型2 异常引用2){
//异常处理代码2
}
......
finally{
//最终执行的代码
}
说明:
功能代码:需要将所有可能发生异常的代码放进try块中
若try块中的代码发生异常,将会指向相应的catch块
当try块中的代码出现了异常类型1的异常,则执行异常处理代码1
finally块:最终被执行的代码,无论之前执行的是try块还是catch块,方法结束之前finally块中的代码一 定会执行
public static int fun1() {
try {
throw new Exception();
}catch(Exception e) {
System.out.println("出现异常");
return 1;
}finally {
System.out.println("finally");//这条语句在方法返回1之后执行(最后执行的代码)
//return 2;//若打开此语句注释,则这个方法的返回值一定是2
}
}
3.使用try-catch结构捕获异常时的注意事项:
1)catch块可以存在多个,但是不能存在try块中不存在的异常
2)上面的catch块不能是下面catch块捕获异常的父类
3)finally块可以省略,根据需求决定是否需要finally块
四、自定义异常类
1.过程:自定义非运行时异常
i.定义一个类,继承Exception类
ii.在此类中定义构造方法,调用父类中的带字符串参数的构造方法(此字符串表示对异常的描述)
iii.使用异常
public class ZDYException extends Exception {
public ZDYException() {}
//此构造方法中的字符串参数表示对此异常的说明描述
public ZDYException(String masage) {
super(masage);
}
}
public class TestZDYException {
public static void main(String[] args) throws ZDYException {
check("123456");
}
//设计一个方法,完成邮箱格式的初步验证(判断传入的字符串是否包含@符)
//若字符串包含@返回true,否则返回false并抛出自定义异常
public static void check(String email){
if(email.contains("@")) {
System.out.println(true);
}else {
System.out.println(false);
try {
throw new ZDYException("没有@符");
} catch (ZDYException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.自定义运行时异常:
i.定义一个类,继承RuntimeException类
ii.在此类中定义构造方法,调用父类中的带字符串参数的构造方法(此字符串表示对异常的描述)
iii.使用异常
public class ZDYRuntime extends RuntimeException {
public ZDYRuntime() {}
public ZDYRuntime(String masage) {
super(masage);
}
}
public class TestZDYRuntime {
public static void main(String[] args) {
throw new ZDYRuntime("hello");
}
}
五、异常声明的方法覆盖
带有异常声明的方法覆盖:
1、方法名、参数列表、返回值类型必须和父类相同
2、子类的访问修饰符与父类相同或是比父类更宽
3、子类中的方法,不能抛出比父类更多、更宽的异常。
代码实现:
//接口:
interface Printable{
public void print() throws IOException;
}
class MyClass implements Printable{
@Override
public void print() throws IOException{
}
}
//父类
class Super{
public void method() throws Exception{
System.out.println("Super - method()");
}
}
class Sub extends Super{
public void method() throws IOException , ClassNotFoundException, RuntimeException{
System.out.println("Sub - method()");
}
}