文章末尾附有知识点概括(思维导图),有一定基础者可直接浏览
Java异常
有的人认为,异常就代表的项目出现了“问题”,是负面的。但真的是这样么?下面来看个例子:
int a = null ;
int b = Integer.parseInt(a);
在一个系统中当遇到这种情况时,我们设想一下如果系统不报错,哪会有什么后果?此时的b值,应该为多少?
所以异常其实是一种“好事”,如果你合理利用的话。
1. 异常的分类
Java异常千千万万,但是可以粗略的分为两类 Error 和 Exception:
- Error:表示发生严重的错误,程序无法恢复,系统立即崩溃。如:
- OOM(Out Of Memory Error):内存耗尽
- Stack Overflow Error:栈溢出
- Exception:表示程序发生了一些错误,但是可以不影响运行,系统不会立即崩溃。如:
- ClassNotFoundException:为找到类异常
- IOException:IO流异常
进阶理解(初学者可以跳过,但以后要记得回来看):
Java中的异常也是类,父类 Throwable 派生出 Error 和 Exception。 Error 派生会出 OOM、Stack Overflow Error,Exception 会派生出;
Exception类也是同理。如下图
Exception 派生出 两大类 :
一种是逻辑上错误(RuntimeException),如文章开头讲的例子。这种情况应该修改一下代码,不需要捕获。
第二种就是很可能会发生的错误(checked Exception):例如当你使用IO读取文件时,很有可能发生错误,所以需要检查。此时你必须捕获,或者声明异常。
2.处理异常
前面说了Exception “可以不影响运行”,如何做到勒?
答案就是捕获异常。
捕获异常 :try catch
try{
// 需要捕获代码放在其中
} catch(Exception e){ //
e.printStackTrace(); // 打印异常
} finally {
// 无论如何都会执行这段代码
}
finally 语句可以省略
2.1多catch语句捕捉
如果使用上面这条语句捕获异常的话,不论发生什么异常都会被捕获。
有的同学可能会说,那不是挺好的么,异常都捕获了。
我们前面已经讲过 RuntimeException是不需要捕捉异常的,但是使用上这种方式则会捕获Runtime Exception。
因此捕获时,我们需要精确的异常的子类
当try块中可能出现多条异常时,此时我们需要多catch语句捕捉异常,若 catch类出先父子类关系
子类catch 应该在 父类 catch 之前
try {
test.send();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// FileNotFoundException 是 IOException 的子类
2.2声明异常
当然除了捕获异常,你还可以在方法上声明异常。
将捕获异常的任务递交至调用方,但最终都要捕获这个异常
public void send() throws FileNotFoundException {
FileInputStream input = new FileInputStream(new File("c://"));
}
使用声明异常,当发生异常时还是会使程序跳出运行
public class Test {
public static void main(String[] args) throws FileNotFoundException {
Test test = new Test();
test.send();
}
public void send() throws FileNotFoundException {
FileInputStream input = new FileInputStream(new File("c://"));
}
}
大家觉得这段程序会使程序中断么?
3.抛出异常
public class ThrowException {
int[] ints = {1,3,4,5,6};
public void increase(){
try{
int num = check(3); // 将参数改为2试试
ints[num]++;
}catch (RuntimeException e){
e.printStackTrace();
}
System.out.println(Arrays.toString(ints));
}
public int check(int num){
for (int i = 0; i < ints.length ; i++) {
if (num == ints[i]) return i;
}
throw new RuntimeException("not num in ints");
}
public static void main(String[] args) {
ThrowException throwException = new ThrowException();
throwException.increase();
}
}
看上面这个程序的优点:
- 当出现错误时 程序能够看到,你不需要再到处找bug
- 出现异常也不会影响程序的运行
4.自定义异常
使用自定义异常,发生异常时可读性更高,且适合不同业务场地开发。
自定义常用异常方法:
- 使用 BaseException继承 合适的Exception,构造方法照抄父类构造方法
public class BaseException extends RuntimeException{
public BaseException() {
super();
}
public BaseException(String message) {
super(message);
}
public BaseException(String message, Throwable cause) {
super(message, cause);
}
public BaseException(Throwable cause) {
super(cause);
}
protected BaseException(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
- 从 BaseException 上派生出 子类异常
public class NumNotInException extends BaseException{
public NumNotInException() {
super();
}
public NumNotInException(String message) {
super(message);
}
public NumNotInException(String message, Throwable cause) {
super(message, cause);
}
public NumNotInException(Throwable cause) {
super(cause);
}
protected NumNotInException(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
然后便可以使用自定义异常了。
throw new NumNotInException(“have Exception”);
总结
直接用一张图对今天的知识点进行概括
若是觉得作者讲的不错可以点个赞,加个关注
我会持续更新哟!