学习内容:异常
1. 异常的概述
1.1 什么是异常?
当程序在执行过程中发生了不正常的情况,这种不正常的情况叫做异常。
1.2 java提供异常处理机制有什么用?
java语言是很完善的语言,提供了异常处理机制,当程序执行过程中出现了不正常情况。java把该异常信息打印输出到控制台,供程序员参考。程序员看到异常信息之后,可以对程序进行修改,让程序更加“健壮”。
1.3 在Java语言中,异常以什么形式存在的呢?
异常在Java语言中以类的形式存在,每一个异常类都可以创建异常对象。
例子:
public class Test01 {
public static void main(String[] args) {
int a =10;
int b =0;
//实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException:("/ by zero");
//并且JVM将new的异常对象抛出,打印输出信息到控制台了。
int result= a/b;
System.out.println(result);
}
}
2. 异常的的继承结构
3. 异常的分类
3.1 异常分为编译时异常和运行时异常。
编译时异常(受检异常、受控异常):是因为程序没有遵循语法规则,编译程序能够自己发现并且提示我们错误的原因和位置。(因为编译异常必须在编译(编写)阶段预先处理,如果不处理,编译器就会报错,因此得名。)
运行时异常(未受检异常、非受控异常):是因为程序在执行时,运行环境发现了不能执行的操作。
编译时异常和运行时异常都是发生在运行阶段。编译阶段异常是不会发生的,因为异常的发生就是new异常对象,只有程序运行阶段才可以new对象。
3.2 编译时异常和运行时异常的区别?
编译时异常一般发生的概率比较高。对于一些发生概率较高的异常,需要在运行之前对其进行预处理。
例:
你看到外面下了很大的雨。
你出门之前预料到:如果不打伞,就可能会生病(发生异常)。而这个异常发生的概率很高,所以出门之前拿一把伞。“拿一把伞”就是对“生病异常”发生之前的一种处理方式。
运行时异常一般发生的概率比较低。
例:
你走在大街上,可能会被天上的飞机轮子砸到(被飞机轮子砸到看做异常)。但是这种异常发生的概率较低。在出门之前你没必要对这种发生概率较低的异常进行预处理。如果预处理这种异常,就会很麻烦。
3. 异常的处理方式
第一种方式: 在方法声明的位置上,使用throws关键字,抛给上一级(调用者)。
修饰符列表 返回值类型 方法名() throws 异常类型{}
第二种方式:使用try…catch语句进行异常捕捉。
try{
需要捕获的代码(会发生异常的语句)
}catch(异常类型 异常名){
处理方案
}
注意:Java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者JVM,JVM知道这个异常发生,就会终止java程序的执行。
4. 拓展
4.1 try...catch...finally
(catch可省,就变为try…finally)
try{
需要捕获的代码(会发生异常的语句)
}catch(异常类型 异常名){
处理方案
}finally{
无论如何都会执行的语句
}
那么问题来了,既然是无论如何都会执行的语句,那try语句里面要是有return呢?大家知道,return会结束当前方法。
例子:
try{
System.out.println("try.....");
return;
}finally{
System.out.println("finally.....");
}
按道理说是应该输出“try…”然后执行return就结束了,但是finally语句又是无论如何都会执行的,所以这不是矛盾了吗?
输出结果:
根据结果我们可以发现,程序执行顺序是:System.out.println("try.....");
----->System.out.println("finally.....");
----->return;
,所以finally里面的语句在return前面执行的。
注意:如果try里面有system.exit();
(退出JVM)
就不会执行了。
那么又有一个问题来了:
public class Test01 {
public static void main(String[] args) {
int result=m();
System.out.println(result);
}
public static int m(){
int i=100;
try{
return i;
}finally {
i++;
}
}
}
输出结果:
这就奇怪了,按上面的结论,这里输出的结果应该是101,为什么输出的是100呢?其实在java中有这样一条规则:**方法体中的代码必须遵循自上而下的顺序依次逐行执行(这是亘古不变的语法)。**因为从顺序上来看return i;
的上面是int i=100;
,所以就算finally里面的语句先执行,但是按照java规则,return输出i的值必须是它上一行语句中i的值。
4.2 throw和throws
throws(自动抛异常)
用在方法声明处,其后跟着的是异常类的名字
表示此方法会抛出异常,需要由本方法的调用者来处理这些异常
但是注意:这只是一种可能性,异常不一定会发生
throw(手动抛异常)
用在方法的内部,其后跟着的是异常对象的名字
表示此处抛出异常,由方法体内的语句处理
注意:执行throw一定抛出了某种异常