Java中的异常(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类。
如果程序没有有效地处理异常,则异常会一直往上抛,最后被JVM抓住,从而中断程序。
特别像人生病的过程,人的免疫系统是抓异常的过程。
学习异常:了解有哪些异常;如何处理异常
异常分两大类:1.非运行异常(编译异常)2.运行时异常
两大类异常要熟记三到五个异常类。
出现的场景:1.IO输入输出异常(处理文件或网络时)
2.解析、转换数据异常(SimpleDateFormat的parse方法)
3.线程操作时异常(线程中断,停止)
4.JDBC操作异常
5.反射操作异常
ParseException 解析异常
IOException IO异常
FileNotFoundException 文件未找到异常
为什么有非运行时异常?
原因是这些场景容易出异常,出异常的几率较高,Java需要我们做异常的提前处理,保证程序运行中不至于因为异常而导致程序中断。
ParseException 解析异常
在编码过程中不需要强制处理的异常,该类异常只有在一定条件下才会抛出异常,在程序运行过程中有可能抛出的异常,叫做运行时异常。
场景:1.数组越界;2.数字运算中被零除;3.定义对象没有实例化就使用,发生空指针异常;4.Scanner要求输入数字nexInt结果输入了非数字,错误输入异常
ArithmeticException 异常
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at C321.Test.main(Test.java:17)
以上信息叫异常堆栈(一层一层的),异常信息是由最底层,最直接发生异常的地方抛出,一路往上抛,直到被try,catch抓住,或者抛进JVM中。
在以上异常中,观察到异常发生的包名"c321",类名"Test",方法名"main",发生异常的代码位置"Test.java的第17行",异常类型是"java.lang.ArrayIndexOutOfBoundsException"
try{}catch{} try块中抛出异常,catch块抓住异常,处理异常,让程序不中断继续运行
try{}catch{}finally{} finally块是无论发生异常还是未发生异常都要执行的语句,存在的意义是释放程序占用的系统资源(IO,JDBC使用的较多)
try{}finally{}比较少见,不处理异常
catch只抓指定的异常
顶层异常类:Throwable代表了所有的异常
第二层:Error(错误,非常严重的错误) Exception(异常,可以处理的)
Error发生的错误大多与运行的环境有关,比如内存溢出,存储介质坏道
第三层:Exception的一个子类RuntimeException(运行时异常)
所有的非运行时异常都继承了Exception(或间接继承)
所有的运行时异常都继承了RuntimeException(或间接继承)
所有的异常如果不是继承RuntimeException就是非运行时异常
throw是抛出单个异常,throws是抛出多个异常
throw是在方法中抛单个异常,throws是在方法声明时抛多个异常
一个是在方法中,一个是在方法头部
throw和catch是二选一,是矛盾的,throw是交给上级处理,catch是自己处理
定义一个方法该方法抛出一个非运行时异常
private static void getDate() throws ParseException {
SimpleDateFormat format =
new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse("2021-3-21");
}
throws抛出异常,转移异常,换一个地方处理异常
throw一般可以不用,JDK中有大量的非运行时异常自动throw,什么时候用throw?当我们想主动抛出异常时用throw。这时候大多抛出的异常是自定义异常。
自己定义异常类,让该类继承Exception
当程序运行时,出现和额、业务规则冲突的情况时,让程序抛出一个自定义异常
比如:性别不是0/1,年龄大于60或小于80,throw new MyException();
try {
getAge();
} catch (AgeException e) {
// 输出异常的信息
System.err.println(e.getMessage());
}
private static void getAge() throws AgeException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入年龄[18-60]:");
int age = scanner.nextInt();
// 用户只要输入的是数字就不会出异常,但是如果不符合我们的业务规则, 则要主动抛出一个异常
if(age<18||age>60){
throw new AgeException("输入的年龄不符合规范");
}
}
当子类的方法(override)重写父类的方法时,子类方法的异常不能强于父类方法的异常:子类方法的异常个数不能大于父类方法的异常个数(throws后面的异常数)
子类方法的异常不能是父类方法异常的父类(父类方法throws ParseException,子类不能抛出ParseException的父类,即Exception)
子类方法的异常类型与父类方法的异常类型是平级的,但不一致。
子类重写的方法异常要么和父类方法的异常相同,要么包含在父类方法的异常中,要么是父类方法异常的子类。
原文:https://www.cnblogs.com/architecture315/p/14773397.html