目录
异常处理:
Throwable类:最顶级的错误类,所有的异常,错误的父类。
自定义异常:
抛出异常:
捕获异常:
异常链:
异常处理:
下标越界
空指针
类型转换异常
数字格式化
算数异常(数字异常)
编程界最常见的几个异常:
除数为0
IO流,没有关闭
停电(现在大多用笔记本,所以现在不怎么出现咯)
当一个程序抛出异常时,抛异常后面的语句将不再执行,类似于return的功能:终止方法的执行。
Throwable类:最顶级的错误类,所有的异常,错误的父类。
Error:正常情况下,一般不太可能出现的。绝大多数Error都会导致程序处于
非正常的状态下,很难恢复。外力的作用下,不考虑。
Error是Throwable的子类。它是在JAVA程序处理范围之外的
Exception:JAVA语言中,将程序执行中发生的不正常的情况下称之为异常。
编译期异常:写代码的时候,抛异常。如果编译器不解决,会编译不通过,一直报红。 运行期异常:RuntimeException,运行时会抛异常,平常没事。
自定义异常:
JAVA中异常机制,但是结合实际业务
怎么自定义异常?
1.所有异常必须是Throwable的子类(大材小用,没必要)
2.如果要定义一个编译期异常,需要继承Exception类
3.如果要定义一个运行期异常,需要继承RuntimeException类
我们为什么要手动抛异常呢?
因为呀,我们要配合全局异常处理机制来解决问题
关于异常,我们就有两个方式:一个是抛出异常,一个是捕获异常
抛出异常:
throw new 异常名("提示");并且必须在方法后面也要抛出异常
(ps:抛出异常可以是多个,用逗号隔开)
public static void fun(int i,int j) throws RuntimeException{
if (j == 0) {
throw new RuntimeException("除数不能为零");
}
System.out.println(i/j);
}
public static void main(String[] args) {
fun(1,0);
}
抛出异常的原理就是这个问题,我不去解决,留给下一个人去解决,直到最后到main方法了,如果不去解决,也抛出那最后就交给了jvm虚拟机了,jvm虚拟机非常累 ,所以我们尽量都在main里或之前就把异常解决了。
捕获异常:
我们通过try..catch语句来展示一下捕获异常:
public static void fun(int i,int j){
System.out.println(i/j);
}
public static void main(String[] args) {
try{
fun(1,0);
}catch (Exception e){
e.printStackTrace();
}
}
把有可能抛异常的代码放到try语句块里,如果有异常,直接在catch里就捕获了,并且代码还能继续执行。
throw语句可以当作方法的返回值,在一个有返回值的方法中,如果有条件分支,一定要保证每种情况下都有返回值。
异常链:
一个异常被抛出去之后会继续被调用这个方法的方法捕获或抛出,异常会扩散。
展示:
public class test04 {
public static void main(String[] args) {
C c=new C();
c.c();
System.out.println("主方法的语句");
}
}
class A{
public void a(){
throw new ServiceException(201,"业务异常...");
}
}
class B{
public void b(){
A aa=new A();
aa.a();
System.out.println("B方法的语句");
}
}
class C{
public void c(){
B b=new B();
b.b();
System.out.println("c方法的语句");
}
}
这样就会报异常:
这就有两个解决方式,要么在B类b方法里捕获异常,要么一直抛出。
捕获异常:
class B{
public void b(){
A aa=new A();
try {
aa.a();
}catch (Exception e){
e.printStackTrace();
}
System.out.println("B方法的语句");
}
}
抛出就不写了,就一直throw new 异常就行了。
try..catch..finally:
这个finally是干什么的呢?
finally是确保里面的语句一定会执行。
有人可能会问:catch捕获异常后语句不也是会运行的吗,那可不一定,如果语句有多个异常呢?那接下来就不会运行了,finally就是保证里面的语句肯定会运行。
try{}catch(){}finally{}
try...catch..finally执行顺序:
finally永远是在最后执行的,而且无论什么情况都会执行除了(System.exit(-1))这是强制退出。
即使在try里return了,也会执行finally,但结果并不会改变try,就相当于try结束了,然后finally单独执行一次,然后return.
(ps:finally类的return没啥用,顶多是不执行try的return,该变得都变了,该不变也没边了。)
catch可以写多个,顺序是从小到大:
try {
System.out.println(num1/num2);
//开发角度来说,应该写指定的。
}catch (ArithmeticException e) {
e.printStackTrace();
System.out.println("除数不能为零");
}catch (Exception e){
System.out.println("未知错误");
}