保姆级别的异常类教学(附代码)
目录
18、final、finally、finalize 有什么区别?
1、什么是异常:
当程序运行时发生的不正常的情况,JAVA会通过JVM给控制台打印一段异常信息给程序员
程序员看到异常信息后,可以对程序进行修改,让程序更加健壮
代码演示:
package com.lbj.javase.exceptionTest;
public class ExceptionTest02 {
public static void main(String[] args) {
int a=10;
int b=0;
//实际上JVM在执行到此处的时候,会new异常对象并且抛出异常,打印输出信息到控制台
//Exception in thread "main" java.lang.ArithmeticException: / by zero
// at com.lbj.javase.exceptionTest.ExceptionTest02.main(ExceptionTest02.java:14)
int c=10/0;
System.out.println(c);
}
}
2、 java语言中异常以什么形式存在的呢?
异常在java中以类的形式存在,每一个异常类都可以创建异常对象
代码演示:
package com.lbj.javase.exceptionTest;
public class ExceptionTest01 {
public static void main(String[] args) {
NumberFormatException nfe=new NumberFormatException("数字格式化异常");
System.out.println(nfe);//java.lang.NumberFormatException: 数字格式化异常
}
}
3、异常对应的现实生活中是怎样的?
举个栗子:
钱包丢了(异常类):
小明钱包丢了(异常对象)
小红钱包丢了(异常对象)
小刚钱包丢了(异常对象)
结论:
类:模板
对象:具体实际存在的个体
4、异常处理机制
Object
Object下有Throwable(可抛出的)
Throwable 下有两个分支:Error(不可处理,直接退出JVM)和Exception(可处理的)
Exception下有两个分支:
Exception的直接子类:编译时异常(要求程序员在编写程序阶段必须预先对异常进行处理,否则编译不通过)
RuntimeException:运行时异常(程序员可以进行处理,也可以不处理让程序照常编译通过即可)
注意:强调!!!所有异常都是发生在运行阶段的
用UML图描述继承结构
UML:统一建模语言,一种图标式语言(画图的)
使用人员:软件架构师、系统分析师、软件设计人员(java开发人员必须要看懂)
作用:描述类和类之间的关系、程序执行的流程、对象的状态等
UML关于异常类的部分结构图:
5、异常处理的具体方式
第一种:在方法声明的位置上,使用throw关键字,抛给上一级(谁调用我,我就抛给谁,抛给上一级)
第二种:使用try...catch语句进行异常的捕捉(这段代码有问题,天知地知你不知我知,因为我捕捉到了)
举个栗子:我是某某集团的一位员工,由于我的失误,导致公司亏损1000元,
“损失的1000元” 可以看做是一个异常发生了,我有两种处理方式
第一种:上报给公司领导,让领导处理
第二种:自己补上这1000元,自己处理
思考:
异常发生后
如果我选择上抛,抛给调用者,调用者需要对这个异常进行处理,那么这个调用者能力足够的话就自己处理,没有能力的话就继续往上抛
如果最后一级实在没办法处理,将终止java程序的执行
员工--》经理--》总经理--》老板
注意:java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者JVM,JVM如果知道这个异常发生,只有一个结果,将终止java程序的执行
6、运行时异常编写程序时可以不处理
运行时,意味着程序的异常可以不进行处理,也能编译通过
代码演示:
package com.lbj.javase.exceptionTest;
public class ExceptionTest03 {
public static void main(String[] args) {
/*
程序执行到此处发生了
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.lbj.javase.exceptionTest.ExceptionTest03.main(ExceptionTest03.java:12)
异常
底层new了一个ArithmeticException异常对象
然后抛出给main方法,main方法没有处理,将这个异常自动抛给了JVM
JVM终止程序执行
*/
System.out.println(100/0);
//这里hello没有执行
System.out.println("hello");
}
}
7、方法声明位置上使用throws
编译时异常,必须进行处理,否则编译器报错
代码演示:
package com.lbj.javase.exceptionTest;
public class ExceptionTest04 {
public static void main(String[] args) {
//main方法调用doSome方法
//我们在调用doSome方法的时候必须对这种异常进行预先的处理
//如果不处理,编译器报错
doSome();
//报错信息
//java: 未报告的异常错误java.lang.ClassNotFoundException; 必须对其进行捕获或声明以便抛出
}
/*
doSome方法在方法声明的位置上使用了throws ClassNotFoundException
这个代码表示doSome()方法在执行过程中,有可能会出现异常
叫做“类没有找到的异常”
直接父类是:Exception
所以ClassNotFoundException属于编译时异常
*/
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome()!!!");
}
}
8、异常处理的原理
第一种处理方式:在方法声明位置继续往上抛(下面这段代码的main方法将异常上抛给了JVM)
上抛类似于推卸责任,继续把异常传递给下一个调用者
package com.lbj.javase.exceptionTest;
public class ExceptionTest05 {
public static void main(String[] args) throws ClassNotFoundException {
doSome();
}
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome()!!!");
}
}
第二种处理方式:try...catch进行捕捉
捕捉相当于把异常拦截下,异常真正解决了,调用者并不会知道自己调用的东西有异常
package com.lbj.javase.exceptionTest;
public class ExceptionTest05 {
public static void main(String[] args) {
try {
doSome();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void doSome() throws ClassNotFoundException{
System.out.println("doSome()!!!");
}
}