栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java异常

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java异常

文章目录
  • 1.什么是异常?
  • 2.异常体系
  • 3.Error
  • 4.Exception
    • 4.1.编译时异常
    • 4.2.RuntimeException
  • 5.编译时异常的处理机制
    • 5.1.throws
    • 5.2.try...catch
    • 5.3.throws和try...catch结合
  • 6.总结

1.什么是异常?

异常是程序在执行的过程中出现的错误。

2.异常体系

3.Error

系统级别异常,出现异常后无法通过程序本身解决的异常,只能重启应用程序。

4.Exception

异常出现后通过程序本身就能解决的异常。

4.1.编译时异常

除了RuntimeException外的异常都是编译异常,它是源码编译前需要处理的异常。

必须明确的一点,编译时异常不是指编译时出现的异常,而是指编译前需要处理的异常,它和所有异常一样都是程序在运行期间出现的错误。

针对某些代码,如果在编译前不进行异常处理,那么就无法通过编译器生成字节码文件。这就是所谓的异常处理,异常处理方式会在稍后进行讲解。

异常处理工作是程序员不得不做的,即使后来程序在运行时没有出现异常。我猜设计师当初这样设计是因为某些代码会经常出现错误,所以必须提前应对。

当程序在JVM运行时真的出现这种异常,就会根据之前的异常处理方案去处理异常。

编译异常和程序员的开发水平和没有一点关系,程序员无法制造编译异常,它往往是因为用户的错误输入导致的异常,比如找不到文件。

编译时异常是可遇而不可求的。

常见的编译异常:
OException:输入输出流异常
FileNotFoundException:文件找不到的异常
ClassNotFoundException:类找不到的异常
DataFormatException:数据格式化异常
NoSuchFieldException:没有匹配的属性异常
NoSuchMethodException:没有匹配的方法异常
SQLException:数据库操作异常
TimeoutException:执行超时异常

4.2.RuntimeException

运行时异常,它是源码编译前不需处理的异常。

如果出现了RuntimeException,那就表示代码设计的逻辑不够严谨,这就是程序员本身的问题了。

常见的运行时异常:
NullPointerException:空指针异常
ArrayIndexOutofBoundsException:数组越界异
ClassCastException:类型转换异常
IllegalArgumentException:非法的参数异常
InputMismatchException:输入不匹配

5.编译时异常的处理机制

异常处理机制有三种,分别是:

  • throws:将方法出现的异常抛给方法调用者,层层往外抛,最终抛给JVM,由JVM出手杀死程序。异常处之前的代码都会执行,异常处之后的代码不会执行。
  • try…catch:将方法出现的异常进行捕捉处理,异常处之前和之后的代码正常执行。
  • throws和try…catch相结合:将需要处理的异常的方法都用throws抛给调用者,层层往外抛,在最外层的调用者进行try…catch统一捕捉异常。

下面通过代码运行实践验证结论:

5.1.throws

代码演示:

//将异常抛给JVM
public static void main(String[] args) throws FileNotFoundException {
        f2();
    }

    //将异常抛给方法调用者main()
    public static void f2() throws FileNotFoundException {
        f1();
        System.out.println("f2...");
    }

    //将异常抛给方法调用者f2()
    public static void f1() throws FileNotFoundException {
        System.out.println("test throws");
        InputStream is = new FileInputStream("e:\2\abc.txt");
        System.out.println("f1...");
    }

测试结果:

由测试结果可以看出,异常出现处即InputStream is = new FileInputStream(“e:2abc.txt”),在它之前的代码都运行了,并立即杀死程序,打印异常的日志信息,在异常处之后的代码明显没有执行。

5.2.try…catch

代码演示:

public static void main(String[] args) {
        f2();
    }

    //自己捕捉异常
    public static void f2()  {
        f1();
        try {
            InputStream is = new FileInputStream("e:\2\abc.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("f2...");
    }

    //自己捕捉异常
    public static void f1()  {
        System.out.println("test throws");
        try {
            InputStream is = new FileInputStream("e:\2\abc.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("f1...");
    }

测试结果:


可以从输出内容看出,异常处之前的代码和之后的代码都被执行了。

关于这个异常处的定义,可要仔细说说了,在throws异常处理机制中,异常处就是出现异常的那一行代码。

可是它在try…catch里的定义可完全和throws的不一样:

在try…catch中异常处是try里面出现异常的那一行及其往后的内容。

try这个关键字可不简单,它会让JVM将出现异常的那一行及其往后的内容看作是一个整体异常处。

请往下看:

public static void main(String[] args) {
        f2();
    }

    //自己捕捉异常
    public static void f2()  {
        f1();
        try {
            InputStream is = new FileInputStream("e:\2\abc.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("f2...");
    }

    //自己捕捉异常
    public static void f1()  {
        System.out.println("test throws");
        try {
            int a = 10,b = 20;
            System.out.println("a:" + a);
            System.out.println("b:" + b);
            InputStream is = new FileInputStream("e:\2\abc.txt");
            System.out.println(sum(a, b));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("f1...");


    }

    public static int sum(int a, int b) {
        return a + b;
    }

测试结果:

从输出的内容可以看出,a和b被输出了,但并没有执行sum(),这是为何?
因为a和b在异常出现的那一行(即InputStream这行)之前,而sum()这一行在InputStream这行之后,JVM认为InputStream这行和及其往后的行是一个整体异常处,所以就不往下执行sum()方法了。

所以我们不要盲目地像别人那样把将所有代码都放在try里面,要谨慎考虑啊。

那什么时候把代码都放进try里面?什么时候又不全放里面了?

答:如果出现异常的那一行代码会影响其在try里它往后的代码,那就都代码放进try里面,因为要保持程序的一致性嘛。相反,出现异常的那一行代码不会影响它往后的代码,那就不要都放进try里,都放进去,你的异常不就连累我其他代码的正常运行吗?

5.3.throws和try…catch结合

代码演示:

public static void main(String[] args) {
        try {
            f2();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    //自己捕捉异常
    public static void f2() throws FileNotFoundException {
        f1();
        InputStream is = new FileInputStream("e:\2\abc.txt");
        System.out.println("f2...");
    }

    //自己捕捉异常
    public static void f1() throws FileNotFoundException {
        System.out.println("test throws");
        InputStream is = new FileInputStream("e:\2\abc.txt");
        System.out.println("f1...");
    }

throws和try…catch相结合,可以省去重复的try…catch工作,将所有异常集中处理,让程序员开发起来变得十分方便。

6.总结

异常是什么?

异常是程序执行中出现的错误。

异常的分类?

  • Errror:系统级别的错误,异常出现后程序本身无法处理,需要重启应用程序。
  • Exception:java.lang包下的异常,异常出现后程序本身就能解决的异常。
  • RuntimeException:运行时异常,源码编译前不需要进行处理的异常。
  • 编译时异常:源码编译前需要进行处理的异常,否则无法通过编译。

编译时异常处理机制有几种?

  • throws:将方法的异常抛给方法的调用者,层层往外抛,直至抛给JVM,让JVM杀死程序,异常处之前的代码都会执行,异常处之后的代码不会执行。
  • try…catch:将方法的异常进行捕捉处理,异常处之前的代码和异常处之后的代码都会正常执行。
  • throws和try…catch结合:将需要处理的异常用throws抛给方法调用者,层层往外抛,在外层的方法调用者中统一用try…catch捕捉处理异常。

需要注意的点:

异常处在throws和try…catch种的定义不一样,在throws里,异常处就是异常出现的那一行,而在try…catch中,异常处是try里异常出现的那一行及其它往后的代码。

三种异常处理机制的比较:

throws是一种不负责任的行为,层层往外抛,最终把“麻烦”抛给虚拟机,运行完程序异常处之前的代码就杀死程序,异常处往后的代码都不会执行。

try…catch是程序自身处理错误,是一种负责任的行为,而且异常处往后的代码也能继续执行,直至程序执行完毕。但是不好的一点是,当方法嵌套过多时,可能有多个方法需要try…catch,非常麻烦。

如果前提是出现异常的那一行代码会影响其在try里它往后的代码,throws和try…catch相结合这种异常处理方案是最优选择,因为它将所有异常都抛给了最外层调用者去统一处理,能为程序员省去不少时间和精力。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014850.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号