Day015 异常处理机制

异常处理的五个关键字

try:监控一个代码块,有异常就能通过catch捕获

catch(想要捕获的异常类型):捕获想要捕获的异常,catch代码块的代码只有在捕获到异常才执行

finally:处理善后工作。不管有没有捕获到异常,finally代码块的代码都会执行

throw用来抛出一个具体的异常类型(用在方法体中,使用throw一定会抛出一个异常)

throws用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁。(用在方法声明后面,表示可能会抛出异常,不一定会抛出)**

如何抛出和捕获异常

首先,我们来先看一个异常

public static void main(String[] args) { int a=1; int b=0; System.out.println(a/b); }

输出结果

Exception in thread "main" java.lang.ArithmeticException: / by zero

用try catch捕获这个异常

public static void main(String[] args) { int a = 1; int b = 0; try { System.out.println(a / b); } catch (ArithmeticException e) { System.out.println("程序出现异常:"+e); } finally { System.out.println("finally"); } }

输出结果

程序出现异常:java.lang.ArithmeticException: / by zero finally

接下来我们把b改为1试一下

public static void main(String[] args) { int a = 1; int b = 1; try { System.out.println(a / b); } catch (ArithmeticException e) { System.out.println("程序出现异常:" + e); } finally { System.out.println("finally"); } }

输出结果:

1 finally

可以发现如果没有捕获到异常,catch代码块是不会执行的,而finally代码块不管有没有捕获到异常都会执行。

通常try和catch一起使用,finally可以不要,finally最常用在一些I/O流、资源类的使用后的关闭工作。

接下来,我们再看一个异常

public class Test { public static void main(String[] args) { new Test().a(); } public void a(){ b(); } public void b(){ a(); } }

输出结果

Exception in thread "main" java.lang.StackOverflowError

​ 因为a调b,b调a,程序陷入死循环,最终导致栈溢出了,接下来我们用上面的方式捕获异常

public class Test { public static void main(String[] args) { try { new Test().a(); } catch (ArithmeticException e) { System.out.println("程序出现异常:" + e); } finally { System.out.println("finally"); } } public void a(){ b(); } public void b(){ a(); } }

输出结果

finally Exception in thread "main" java.lang.StackOverflowError

可以发现没有捕获到异常,这是因为这个异常不是ArithmeticException,而是StackOverflowError,所以当然就捕获不到,接下来回顾一下异常类

Day015 异常处理机制

我们知道了这是个栈溢出异常,要用StackOverflowError或者它的父类来捕获,假设我不知道它会抛出什么异常,我直接用异常的超类Throwable捕获也是可以的。

public class Test { public static void main(String[] args) { try { new Test().a(); } catch (Throwable e) { System.out.println("程序出现异常:" + e); } finally { System.out.println("finally"); } } public void a(){ b(); } public void b(){ a(); } }

输出结果

程序出现异常:java.lang.StackOverflowError finally 捕获多个异常

还是上面的例子,这次我们捕获多个异常,我们知道Error和Throwable都能捕获到异常

public class Test { public static void main(String[] args) { try { new Test().a(); } catch (Exception e) { System.out.println("Exception捕获:" + e); } catch (Error e) { System.out.println("Error捕获:" + e); } catch (Throwable e) { System.out.println("Throwable捕获:" + e); } finally { System.out.println("finally"); } } public void a() { b(); } public void b() { a(); } }

输出结果:

Error捕获:java.lang.StackOverflowError finally

​ 我们发现只被Error捕获,多个catch最终只有一个catch捕获到异常,接下来我们把Error和Throwable调换一下

public class Test { public static void main(String[] args) { try { new Test().a(); } catch (Exception e) { System.out.println("Exception捕获:" + e); } catch (Throwable e) { System.out.println("Throwable捕获:" + e); } catch (Error e) {//编译报错了Exception 'java.lang.Error' has already been caught System.out.println("Error捕获:" + e); } finally { System.out.println("finally"); } } public void a() { b(); } public void b() { a(); } }

​ 直接编译报错了Exception 'java.lang.Error' has already been caught,因为我们已经通过Throwable先捕获异常了,而Error是Throwable的子类,所以这个Error的catch永远不会被执行。因此捕获多个异常应该按从小(异常子类)到大(异常父类)的顺序捕获

快速捕获异常快捷键

选中需要捕获异常的代码,ctrl+alt+t

throw主动抛出异常

我们程序中一些我们已经预知的异常,我们可以通过throw主动抛出

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwysxy.html