博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java异常知识总结
阅读量:2428 次
发布时间:2019-05-10

本文共 4141 字,大约阅读时间需要 13 分钟。

1.为什么需要异常

在没有异常机制的时候我们对错误处理一般是这样实现的:通过函数的返回值来判断是否发生了异常(这个返回值通常是已经约定好了的),调用该函数的程序负责检查并且分析返回值。虽然可以解决异常问题,但是这样做存在以下缺陷:

  1. 标准不统一。返回值的约定依赖于实现者个人,可能造成标准不一致。
  2. 代码可读性与可维护性降低。将异常处理代码和程序代码混淆在一起不方便阅读,更不利于后期维护。

为了解决上述存在的问题,引入了异常机制。它在程序发生异常时,强制终止程序运行,记录异常信息并将这些信息反馈给我们,由我们来确定是否处理异常。它能使我们摆脱各种返回值的约定以及实现逻辑代码与错误处理代码的分离。

2.异常体系介绍

这里写图片描述

从图中可以看出Throwable是java所有Error和Exception的超类。

Error和Exception的区别

  • Error是程序无法处理的,如OutOfMemoryError、ThreadDeath等,出现这种情况程序将无能为力,交由JVM来处理,不过JVM在大多数情况下会选择终止线程。
  • Exception是程序正常运行中可以预料的意外情况,可能应该被捕获,进行相应处理。

CheckedException和RuntimeException的区别

  • CheckedException在源代码里必须显式地进行进行捕获处理。这是编译检查的一部分。
  • RuntimeException是运行时异常,在编译阶段不会进行检查。

3.异常语法

java 异常相关的关键字有5个:try, catch, finally, throw, throws。

语法形式

try {      // 可能会发生异常的程序代码  } catch (ExceptionType1 id1) {      // 捕获并处理try抛出的异常类型Type1  } catch (ExceptionType2 id2) {      // 捕获并处理try抛出的异常类型Type2  } finally {      // 无论是否发生异常,都将执行的语句块  }

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。

catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。

public class Main {    public static void main(String[] args)  {        try {            int i = 1 / 0;            return;        } catch (ArithmeticException e) {            e.printStackTrace();        } catch (NullPointerException e){            e.printStackTrace();        } finally {            System.out.println("finally");        }    }}

运行结果:

finallyjava.lang.ArithmeticException: / by zero    at com.tongfang.learn.Main.main(Main.java:36)

在以下特殊情况下,finally块不会被执行:

  • 在finally语句块中发生了异常。
public class Main {    public static void main(String[] args)  {        try {            int i = 1 / 0;        } catch (ArithmeticException e) {            e.printStackTrace();        } catch (NullPointerException e){            e.printStackTrace();        } finally {            throw new NullPointerException();            System.out.println("finally"); //编译错误,语句不可达        }    }}
  • 在前面的代码中用了System.exit()退出程序。
public class Main {    public static void main(String[] args)  {        try {            System.exit(0);        } catch (ArithmeticException e) {            e.printStackTrace();        } catch (NullPointerException e){            e.printStackTrace();        } finally {            System.out.println("finally");        }    }}

运行结果:

Process finished with exit code 0

throw:对于异常可以捕获,也可以抛出,该关键字用于抛出异常,让调用者来捕获。

throws:声明一个方法可能抛出的异常。

catch匹配

异常的捕获顺序为按照程序中定义的异常顺序依次匹配,当匹配到对应的异常则进入异常处理程序。

我们看下面的程序:

public class Main {    public static void main(String[] args)  {        try {            int i = 1 / 0;        } catch (Exception e){                    e.printStackTrace();        } catch (ArithmeticException e) {   //编译错误            e.printStackTrace();        } finally {            System.out.println("finally");        }    }}

按照catch匹配原则,本例中ArithmeticException是Exception的子类,所有的Exception 将会被第一个catch捕获,后面的catch将永远不可达,所以会编译报错。因此catch 代码应按照先捕获小异常,再捕获大异常的原则实现。

异常对继承的影响

方法重写中声明异常原则:

  • 父类没有声明异常,子类则不能。
class A{
public void method() { }}class B extends A{
public void method() throws FileNotFoundException { //编译错误,父类中该方法没有声明抛出异常。 }}
  • 子类不可抛出比父类更抽象的异常类,也就是子类抛出的异常类只能是父类中抛出的异常类的子类。
class A{
public void method() throws IOException{ }}class B extends A{
public void method() throws Exception { //编译错误,抛出的Exception是IOException的父类 }}
class A{
public void method() throws IOException{ }}class B extends A{
public void method() throws FileNotFoundException { //编译通过 }}

自定义异常:

所有异常都必须是 Throwable 的子类。

如果希望写一个检查性异常类,则需要继承 Exception 类。
如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

例:

class MyException extends Exception {
public MyException() { } public MyException(String message) { super(message); }}public class Main {
public static void main(String[] args) { try { throw new MyException("myException"); } catch (MyException e){ System.out.println(e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } finally { System.out.println("finally"); } }}

运行结果:

myExceptionfinallyProcess finished with exit code 0
你可能感兴趣的文章
程序员惊魂 12 小时:“���”引发线上事故
查看>>
调查了 10,975 位 Go 语言开发者,我们有了这些发现!
查看>>
面试官吐槽:“Python程序员就是不行!”网友:我能把你面哭!
查看>>
太真实!深刻解读论文里的话术| 每日趣闻
查看>>
拿来就能用!Python 每天定时发送一句情话 | 原力计划
查看>>
Java“拍了拍”你,面试其实没那么难...
查看>>
帅爆了!3个月0基础转型头条数据分析师,他做对了什么?
查看>>
程序员:我受够了!不想再在小厂里干Java了!
查看>>
厉害!国内大学生计算机编程第一人,一人挑战一个队,百度最年轻 T10,现创业自动驾驶...
查看>>
研发团队来了高颜值的妹子,这结局万万没想到 | 每日趣闻
查看>>
太难了!开源项目如何商业化?
查看>>
谷歌排名第一的编程语言,死磕它这两点,小白也能学的会!不信你看!
查看>>
程序员掉头发的原因找到了 | 每日趣闻
查看>>
腾讯:我就是那只吃了假辣椒酱的憨憨。老干妈:企鹅你可长点心吧!
查看>>
倒计时1天 | 张钹院士领衔,AI开发者大会20大论坛全攻略!
查看>>
运维工程师的日常?? | 每日趣闻
查看>>
31 道 Java 核心面试题,统统打包给你!
查看>>
太拼了:谷歌第一编程语言小白也能学会!
查看>>
三分钟黑了阿里?马云下死命令留他?吴翰清辟谣:我没黑过阿里
查看>>
如果重新一次高考,你还会选择软件专业当程序员吗? | 每日趣闻
查看>>