异常
一、
1、异常旗下两大分支:编译时异常和运行时异常
Exception->RunTimeException(运行时异常,又叫未受检异常、非受控异常),编写阶段可不处理,编译器没意见。
Exception->ExceptionSubClass(编译时异常,又叫受检异常、受控异常),是Exception的直接子类,编写程序时必须处理,不然报错。发生概率极高。
切记:所有异常都是发生在运行阶段的。
2、处理异常
第一种:在方法声明的位置上,使用throws关键字,抛给上一级。
eg:我是一个小职员,失误了,导致公司损失1000块,然后告诉了领导,这就是异常的上抛
第二种:使用try..catch语句进行异常捕捉。
eg:我还是那个小职员,但是我这次不告诉领导了,直接用我自己的钱补上,这就是异常的捕捉
注意:java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者JVM,JVM知道这个异常发生,只有一个结果,终止java程序的执行。
异常处理机制的作用就是增强程序的健壮性,争取做到发生异常也不影响程序的执行
3、方法声明位置上使用throws
Eg:
public static void doSome() throws ClassNotFoundException(){
Sout("dosome!!!");
}
这个时候要想在主方法直接调用doSome的话,那编译器就会报错(错误信息:未处理的异常,Unhandled exception)。
4、try..catch
语法:
try{
// 尝试,把可能出现问题的代码块放到这里
}catch(异常类 + 变量名){
//catch是捕捉到异常之后执行的分支,如输出一些错误信息
// 变量里面存的是异常对象的内存地址
}
// try..catch抓住异常之后,这里的代码会继续执行。
捕捉等于把异常拦下来,异常真正的解决了,调用者不知道发生过异常。
5、throws
throws相当于把异常上抛,推卸责任。但是要注意,抛出异常之后,当前方法就没有责任了,把责任抛给上级了。且
①往上抛的过程中,只能抛当前异常类及父异常类,级别低了不行。
②可以同时抛出多个异常
③一般不建议在main方法上使用throws
6、深入try…catch…
try{
FileInputStream fis =new FileInputStream("XXXXX");
//这里new了一个异常对象,try里发现异常,于是转交catch捕捉
}catch(Exception e){ // 异常类可以是当前异常类,也可以是其父类。
Sout("文件不存在 !");
}
①catch可以写多个。建议catch的时候,精确的一个一个处理,这样有利于程序的调试,也可以直接来一个catch(Exception e) ,省事。
②多个catch遵循"从上到下,从小到大"的原则
7、jdk8新特性
允许这么写catch(FileNotFoundException | ArithmeticException | NullPointerException),即以“或”的方式来写异常,方便处理
8、异常和捕捉怎么选择?
如果希望调用者来处理,throws上报;其他情况,直接捕捉。只有这一个原则
二、getMessage() 和 printStacktrace()方法
1、getMessage()方法
作用:获取异常的简单的描述信息,其实就是构造方法上String参数(传进去的)
String msg = exception.getMessage();
2、printStackTree()方法
作用:打印异常追踪的堆栈信息
Exception.printStackTrace();
3、举个例子
Eg:
NullPointerException e = new NullPointerException("空指针异常abc");
String msg = e.getMessage();
Sout(msg); // 输出了“空指针异常abc”
e.printStackTrace(); //会输出一堆错误代码之类的东西。这行代码要写上,不然出问题你也不知道,养成好习惯。
三、关于try…catch中的finally子句
1、在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常。finally子句必须和try一起出现,不能单独编写。
2、finally子句通常使用在哪种情况下呢?
通常在finally语句块中完成资源的释放/关闭,因为finally中的代码比较有保障,即使try语句块中的代码出现异常,finally中的代码也会正常执行。(finally中的代码一定会执行,但一种情况除外,就是退出JVM,退出JVM之后,finally不会执行)
3、
try和finally,没有catch也可以。即try和finally可以联合使用,但try不能单独使用
四、java中怎么自定义异常呢
两步:
第一步:编写一个类继承Exception或者RuntimeException
第二步:提供两个构造方法,一个无参数的,另一个带有String参数的
死记硬背就行,先不用管为什么
eg:
public class HelloIDEA {
public static void main(String[] args) {
MyException e = new MyException("用戶名不能為空");
e.printStackTrace();
System.out.println(e.getMessage());
}
}
class MyException extends Exception{
public MyException(){
}
public MyException(String s){
super(s);
}
}
输出信息如下:
D:\Java\bin\java.exe "-javaagent:D:\重装之后的IDEA\IntelliJ IDEA Community Edition 2021.1.3\lib\idea_rt.jar=54525:D:\重装之后的IDEA\IntelliJ IDEA Community Edition 2021.1.3\bin" -Dfile.encoding=UTF-8 -classpath D:\java项目(idea)\out\production\java项目(idea) come.wkcto.HelloIDEA
come.wkcto.MyException: 用戶名不能為空
at come.wkcto.HelloIDEA.main(HelloIDEA.java:6)
用戶名不能為空