• java异常处理


    异常(Exception)的概念

    异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。

    传统的异常处理方式多采用标识程序出现的异常情况。如使用if分支来处理可能发生的异常。这会有多个坏处:

    1. 逻辑代码和错误处理代码放一起!

    2. 程序员本身需要考虑的例外情况较复杂,对程序员本身要求较高!

    在Java的异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。异常类定义中包含了该类异常的信息和对异常进行处理的方法。

    所谓异常处理,就是指程序在出现问题时依然可以正确的执行完

    Java是采用面向对象的方式来处理异常的。处理过程:

    1. 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。

    2.  捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

    异常分类

    JDK 中定义了很多异常类,这些类对应了各种各样可能出现的异常事件,所有异常对象都是派生于Throwable类的一个实例。如果内置的异常类不能够满足需要,还可以创建自己的异常类。

    Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception。

     Error

    Error是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

    Error表明系统JVM已经处于不可恢复的崩溃状态中。我们不需要管它。

     Exception

     Exception是程序本身能够处理的异常,如:空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算术异常(ArithmeticException)等。

     Exception类是所有异常类的父类,其子类对应了各种各样可能出现的异常事件。 通常Java的异常可分为:

    1. RuntimeException 运行时异常

    2. CheckedException 已检查异常

    Error与Exception的区别

    1. 我开着车走在路上,一头猪冲在路中间,我刹车。这叫一个异常。

    2.  我开着车在路上,发动机坏了,我停车,这叫错误。系统处于不可恢复的崩溃状态。发动机什么时候坏?我们普通司机能管吗?不能。发动机什么时候坏是汽车厂发动机制造商的事。

    异常处理的方式:try-catch-finally

    异常处理的方式有两种:使用“try-catch-finally”捕获异常、使用“throws”。

    语法:
    try{
      可能出现异常的代码片段

    }catch(Exception e){//一般最后一个catch捕获的是Exception 这样可以避免因为未捕获的异常而导致程序中断

      当try中出现XXXException后的解决办法
    }finally{

      无论是否捕获异常里面代码都将会执行

      }

    finally块

    finally块是异常处理机制的最后一块 他可以直接跟在try语句块之后(相对少) 或者最后一个catch块之后。

    finally确保只要程序进行try块中,那么finally块中的代码必定执行(无论try-catch仲有无return)。

    所以通常我们将无论程序是否出现异常,都要继续去执行的代码放在finally块中。 如:IO操作后的关闭流。

    注:finally中一般不会去写return 因为只要finally有return 前面的所有return语句全部没用。

    自动关闭特性

    JDK7之后推出的 使得我们在IO操作中的异常处理写法更加简洁。编译器最终会在编译时将代码改为传统的try-catch-finally的形式,并在finally中关闭这里定义的流

    例 try(FileOutputStream fos=new FileOutputStream("fos.txt"){
    。。。。。。。
    }catch{......}

    注:try小括号中只能写流 (只能写实现了Autocloseble类的 ,所有的流都实现了这个类)。

    异常处理的方式: throws

    通常遇到以下两种情况是我们会主动向外抛出异常

    1. 当遇到满足语法要求但是不符合业务逻辑要求时主动向外抛出异常。

    2. 程序确实出现了异常,但是异常不应该在当前代码片段中被解决。

    语法:

    使用throws关键字在方法头部抛出异常。如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常之间以逗号隔开。

    public static void readFile(String fileName)throws IOException {

    }

    必要检查异常、非必要检查异常

    如果所有异常都是必要检查异常 则异常检查就成了代码必要的部分 会使代码非常的啰嗦。
    只有 RuntimeException及其子类属于常识性异常 无需检查异常 、像空指针异常、数组越界都是 无需做异常检查自己注意就行。

    自定义异常类

    1.在程序中,可能会遇到JDK提供的任何标准异常类都无法充分描述清楚我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。

    2.自定义异常类只需从Exception类或者它的子类派生一个子类即可。

    3.自定义异常类如果继承Exception类,则为受检查异常必须对其进行处理,如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类

    使用自定义异常类的步骤

    1.创建一个自定义的异常类,如IllegalAgeException,使其继承Exception,并设置序列号版本serialVersionUID。

    2.利用eclipse中的Source->Generate  Constructors fromSuperclass 来继承父类Exception的构造方法。

    3.在可能抛出此异常的方法首部添加throws关键字抛出自定义异常类,在此方法内部添加throw new  IllegalAgeException("*xxxx") 使得如果调用此方法不满足特定条件时打印错误信息。如果是throw new RuntimeException("xxx") 则方法首部可以不用添加throws关键字来抛出此异常。例如:

     
    //IllegalAgeException为自定义异常
    public void setAge(int age) throws IllegalAgeException { if (age < 0) { throw new IllegalAgeException("人的年龄不应该为负数"); } this.age = age; }
    注:这时如果在调用此方法则需要对此进行异常处理,使用try-catch或throws向上一级抛出。


    //若抛出的是RuntimeException或是其子类则无需再方法首部添加throws
    public void setAge(int age) {
            if (age < 0) {
                throw new RuntimeException("人的年龄不应该为负数");
            }
            this.age = age;
        }
    注:此时若调用此方法无需对此进行异常处理。

    throws 和 throw

    throw是用来抛出异常的 ,throws是用来嘱咐编译器当调用这个方法时要进行异常处理。

    1.throws可以理解为时丑话说在前面,就是我明确告诉你调用我这个方法可能会报这个错误,调用它时你必须要处理这个异常当。某个方法可能会抛出某种异常时用于throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理。(处理时该我们自己管 用try-catch ,不该我们管用throws声明该异常的抛出。)

    2.throw是抛出一个异常的实例,总是出现在函数体中程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

    3.一般情况要在方法声明后面写throws,告诉调用者调用这个方法时有可能要抛出什么异常 必须要进行处理。实际上java除了RuntimeException及其子类型异常时不用throws, 其他异常必须要在方法声明后面加throws xxx。

    4. throws可以单独使用,但throw不能;throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获。

    5.一定不要在main函数写throws 。

    子类在重写超类中含有throws声明异常抛出的方法时的重写规则

    可以是和父类一样的形式去重写 即父类抛出多少异常子类也抛出多少
    允许不抛出任何异常
    允许仅抛出部分异常
    允许抛出父类方法抛出异常的子类型异常
    不允许抛出额外异常
    不允许抛出父类抛出异常的父类型异常

    异常常用的方法 

    void printStackTrace() //打印错误堆栈信息,助于定位错误并改正。调试错误信息时,看at后面是自己的包。

    String getMessage() //错误信息的描述

  • 相关阅读:
    stty
    ping
    read
    echo
    grep
    date
    vi与vim编辑器使用
    rename
    netstat
    input输入框的背景图片也可以这样玩
  • 原文地址:https://www.cnblogs.com/zqf-bczl/p/13713401.html
Copyright © 2020-2023  润新知