查看: 100|回复: 0

JavaSE学习笔记(6)---异常

[复制链接]
发表于 2020-2-16 11:23:26 | 显示全部楼层 |阅读模式
JavaSE学习条记(6)---非常

软件步伐在运行过程中,非常大概遇到题目,我们称之为非常,英文是:Exception,意思是例外。遇到这些例外环境,或者叫非常,我们怎么让写的步伐做出公道的处理,安全的退出,而不至于步伐瓦解呢?
1.非常产生的缘故原由及利用原则

在 Java 中一个非常的产生,主要有如下三种缘故原由:

  • Java 内部错误发生非常,Java 虚拟机产生的非常。
  • 编写的步伐代码中的错误所产生的非常,比方空指针非常、数组越界非常等。这种非常称为未检査的非常,一样平常需要在某些类中会合处理这些非常。
  • 通过 throw 语句手动生成的非常,这种非常称为检査的非常,一样平常用来告知该方法的调用者一些必要的信息。
Java 通过面向对象的方法来处理非常。在一个方法的运行过程中,假如发生了非常,则这个方法会产生代表该非常的一个对象,并把它交给运行时的系统,运行时系统探求相应的代码来处理这一非常。
我们把生成非常对象,并把它提交给运行时系统的过程称为拋出(throw)非常。运行时系统在方法的调用栈中查找,直到找到可以或许处理该类型非常的对象,这一个过程称为捕捉(catch)非常
Java 非常逼迫用户思量步伐的矫健性和安全性。非常处理不应用来控制步伐的正常流程,其主要作用是捕捉步伐在运行时发生的非常并进行相应处理。编写代码处理某个方法大概出现的非常,可遵循如下三个原则:

  • 在当前方法声明中利用 try catch 语句捕捉非常。
  • 一个方法被覆盖时,覆盖它的方法必须拋出相同的非常或非常的子类。
  • 假如父类抛出多个非常,则覆盖方法必须拋出那些非常的一个子集,而不能拋出新非常。
2.非常的类型

在 Java 中全部非常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于非常类层次结构的顶层。Throwable 类下有两个非常分支 ExceptionError,如图所示。

Throwable 类是全部非常和错误的父类,下面有 Error 和 Exception 两个子类分别表现错误和非常。此中非常类 Exception 又分为运行时非常和非运行时非常,这两种非常有很大的区别,也称为不检查非常(Unchecked Exception)和检查非常(Checked Exception)。

  • Exception 类用于用户步伐大概出现的非常环境,它也是用来创建自定义非常类型类的类。
  • Error 定义了在通常环境下不希望被步伐捕捉的非常。Error 类型的非常用于 Java 运行时由系统显示与运行时系统本身有关的错误。堆栈溢出是这种错误的一例。
  • 本章不讨论关于 Error 类型的非常处理,因为它们通常是劫难性的致命错误,不是步伐可以控制的。本章接下来的内容将讨论 Exception 类型的非常处理。
运行时非常都是 RuntimeException 类及其子类非常,如 nullPointerException、IndexOutOfBoundsException 等,这些非常是不检查非常,步伐中可以选择捕捉处理,也可以不处理。这些非常一样平常由步伐逻辑错误引起,步伐应该从逻辑角度尽大概避免这类非常的发生。
非运行时非常是指 RuntimeException 以外的非常,类型上都属于 Exception 类及其子类。从步伐语法角度讲是必须进行处理的非常,假如不处理,步伐就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 非常,一样平常环境下不自定义检查非常。下表中列出了一些常见的非常类型及它们的作用。
非常类型说明Exception非常层次结构的根类RuntimeException运行时非常,多数 java.lang 非常的根类ArithmeticException算术谱误非常,如以零做除数ArraylndexOutOfBoundException数组大小小于或大于现实的数组大小NullPointerException实验访问 null 对象成员,空指针非常ClassNotFoundException不能加载所需的类NumberF ormatException数字转化格式非常,比如字符串到 float 型数字的转换无效IOExceptionI/O 非常的根类F ileN otF oundException找不到文件EOFException文件竣事InterruptedException线程中断IllegalArgumentException方法接收到非法参数ClassCastException类型转换非常SQLException操作数据库非常3.非常的处理

1.捕捉非常

捕捉非常是通过3个关键词来实现的:try-catch-finally。用try来执行一段步伐,假如出现非常,系统抛出一个非常,可以通过它的类型来捕捉(catch)并处理它,末了一步是通过finally语句为非常处理提供一个同一的出口,finally所指定的代码都要被执行(catch语句可有多条;finally语句最多只能有一条,根据本身的需要可有可无)。如图所示。

上面过程详细剖析:
1. try:
try语句指定了一段代码,该段代码就是非常捕捉并处理的范围。在执行过程中,当任意一条语句产生非常时,就会跳过该条语句中背面的代码。代码中大概会产生并抛出一种或几种类型的非常对象,它背面的catch语句要分别对这些非常做相应的处理。
一个try语句必须带有至少一个catch语句块或一个finally语句块 。
留意事项
当非常处理的代码执行竣事以后,不会回到try语句去执行尚未执行的代码。
2. catch:
n-每个try语句块可以陪同一个或多个catch语句,用于处理大概产生的不同类型的非常对象。
n-常用方法,这些方法均继承自Throwable类 。
u-toString ()方法,显示非常的类名和产生非常的缘故原由
u-getMessage()方法,只显示产生非常的缘故原由,但不显示类名。
u-printStackTrace()方法,用来跟踪非常变乱发生时堆栈的内容。
n-catch捕捉非常时的捕捉顺序:
u-假如非常类之间有继承关系,在顺序安排上需留意。越是顶层的类,越放在下面,再不然就直接把多余的catch省略掉。 也就是先捕捉子类非常再捕捉父类非常。
2. finally:
n-有些语句,不管是否发生了非常,都必须要执行,那么就可以把这样的语句放到finally语句块中。
n-通常在finally中关闭步伐块已打开的资源,比如:关闭文件流、释放数据库连接等。
try-catch-finally语句块的执行过程:
try-catch-finally步伐块的执行流程以及执行结果比较复杂。
根本执行过程如下:
步伐起首执行大概发生非常的try语句块。假如try语句没有出现非常则执行完后跳至finally语句块执行;假如try语句出现非常,则中断执行并根据发生的非常类型跳至相应的catch语句块执行处理。catch语句块可以有多个,分别捕捉不同类型的非常。catch语句块执行完后步伐会继承执行finally语句块。finally语句是可选的,假如有的话,则不管是否发生非常,finally语句都会被执行。
留意事项

  • 纵然try和catch块中存在return语句,finally语句也会执行。是在执行完finally语句后再通过return退出
  • finally语句块只有一种环境是不会执行的,那就是在执行finally之前遇到了System.exit(0)竣事步伐运行
典型代码
  1. import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class Test8 {    public static void main(String[] args) {        FileReader reader = null;        try {            reader = new FileReader("d:/a.txt");            char c = (char) reader.read();            char c2 = (char) reader.read();            System.out.println("" + c + c2);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (reader != null) {                    reader.close();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }}
复制代码
2.抛出非常

当CheckedException产生时,不一定立刻处理它,可以再把非常throws出去。
在方法中利用try-catch-finally是由这个方法来处理非常。但是在一些环境下,当前方法并不需要处理发生的非常,而是向上传递给调用它的方法处理。
假如一个方法中大概产生某种非常,但是并不能确定如那边理这种非常,则应根据非常规范在方法的首部声明该方法大概抛出的非常。
假如一个方法抛出多个已检查非常,就必须在方法的首部列出全部的非常,之间以逗号隔开。
留意事项
方法重写中声明非常原则:子类重写父类方法时,假如父类方法有声明非常,那么子类声明的非常范围不能超过父类声明的范围。
典型代码
  1. import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException; public class Test9 {    public static void main(String[] args) {        try {            readFile("joke.txt");        } catch (FileNotFoundException e) {            System.out.println("所需文件不存在!");        } catch (IOException e) {            System.out.println("文件读写错误!");        }    }      public static void readFile(String fileName) throws FileNotFoundException,              IOException {        FileReader in = new FileReader(fileName);        int tem = 0;        try {            tem = in.read();            while (tem != -1) {                System.out.print((char) tem);                tem = in.read();            }        } finally {            in.close();        }    }}
复制代码
4.自定义非常


  • 在步伐中,大概会遇到JDK提供的任何标准非常类都无法充实描述清晰我们想要表达的题目,这种环境下可以创建本身的非常类,即自定义非常类。
  • 自定义非常类只需从Exception类或者它的子类派生一个子类即可。
  • 自定义非常类假如继承Exception类,则为受检查非常,必须对其进行处理;假如不想处理,可以让自定义非常类继承运行时非常RuntimeException类。
  • 风俗上,自定义非常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。
示例
自定义非常:
  1. /**IllegalAgeException:非法年事非常,继承Exception类*/class IllegalAgeException extends Exception {    //默认构造器    public IllegalAgeException() {         }    //带有详细信息的构造器,信息存储在message中    public IllegalAgeException(String message) {        super(message);    }}
复制代码
自定义非常的利用:
  1. class Person {    private String name;    private int age;     public void setName(String name) {        this.name = name;    }     public void setAge(int age) throws IllegalAgeException {        if (age < 0) {            throw new IllegalAgeException("人的年事不应该为负数");        }        this.age = age;    }     public String toString() {        return "name is " + name + " and age is " + age;    }} public class TestMyException {    public static void main(String[] args) {        Person p = new Person();        try {            p.setName("Lincoln");            p.setAge(-1);        } catch (IllegalAgeException e) {            e.printStackTrace();            System.exit(-1);        }        System.out.println(p);    }}
复制代码
执行结果:

5.利用非常机制的发起

1.要避免利用非常处理取代错误处理,这样会降低步伐的清晰性,而且效率低下。
2.处理非常不可以取代简朴测试---只在非常环境下利用非常机制。
3.不要进行小粒度的非常处理---应该将整个任务包装在一个try语句块中。
4.非常每每在高层处理(先相识!背面做项目会说!) 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?用户注册

x

相关技术服务需求,请联系管理员和客服QQ:2753533861或QQ:619920289
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

帖子推荐:
客服咨询

QQ:2753533861

服务时间 9:00-22:00

快速回复 返回顶部 返回列表