• 异常


    三种异常类型

    1. 检查性异常:最具代表的检查异常时用户错误或问题引起的异常,这是程序员无法预见的,例如要打开一个不存在的文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

    2. 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。

    3. 错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

     

    Throwable(异常的超类)

    1. ERROR(错误)

      • VirtulMachineError(虚拟机异常)

        • StackOverFlowError

        • OutOfMemoryError

      • AWTError(GUI编程图形界面化异常)

    2. Exception(异常)

      • IOException(IO异常)

        • EOFException

        • FileNotFoundException

      • RuntimeException(运行时异常)

        • ArrithmeticException(算数异常)

        • MissingResourceException(丢失资源)

        • ClassNotFoundException(找不到类)

        • NullPointerException(空指针异常)

        • IllegalArgumentException

        • ArrayIndexOutOfBoundsException(数组下标越界异常)

        • UnkownTypeException(未知的类型异常)

    Error与Exception区别

    Error通常时灾难性的致命错误,时程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

    异常处理机制

    • 抛出异常

    • 捕获异常

    • 异常处理五个关键字:

      • try、catch、finally、throw、throws 

    捕获异常 try...catch

    捕获异常:Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式处理。

    捕获异常语法如下:

    try:该代码块中编写可能产生异常的代码。

    catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。

    注意:try和catch都不能单独使用,必须连用。

    Finally 块

    有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到,而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。

    什么时候的代码必须最终执行?

    当我们在try语句块中打开了一些物理资源(如 IO流、网络、数据库链接等),都需在使用完之后,最终关闭打开的资源。

    finally 的语法: try.....catch...finally:自身需要处理异常,最终还得关闭资源。

    注意:finally 不能单独使用。

      

     1  package com.exception;
     2  public class Test {
     3      public static void main(String[] args) {
     4          int a=1;
     5          int b=0;
     6          //快捷键 ctrl+alt+t
     7          System.out.println(a/b);
     8          //要捕获多个异常:从小到大!
     9          try {//try监控区域
    10              new Test().a(); 
    11          }catch (ArithmeticException e){//catch(想要捕获的异常类型!) 捕获异常
    12              System.out.println("程序出现异常,变量b不能为0" );
    13          }catch (Error e){
    14              System.out.println("Error");
    15          }catch (Exception e){
    16              System.out.println("Exception ");
    17          } finally {//处理善后工作
    18              System.out.println("finally");
    19          }
    20          //finally 可以不要finally 假设IO,资源,关闭!
    21      }
    22      public void a(){
    23          b();
    24      }
    25      public void b(){
    26          a();
    27      }
    28  } 
    抛出异常 throw

    在Java中,提供一个throw关键字,它用来抛出一个指定的异常对象。

    1. 创建一个异常对象。封装一些提示信息(信息可以自己编写)

    2. 需要将这个异常对象告知调用者。通过关键字throw将这个异常对象传递到调用者处。throw用在方法内,用来抛出一个异常对象,将使用格式: throw new 异常类名(参数---你想告知用户的异常信息);

    注意:如果产生了问题,我们通过throw将异常进行抛出,也就是将问题返回给该方法的调用者。那么调用者该怎么处理那?一种是进行捕获处理,另一种就是继续将问题生命出去,使用throws声明处理。

    声明异常 throws

    将问题标识出来,报告给调用者。如果方法内通过throw抛出了 编译时异常,而没有捕获处理,那么必须通过throws 进行声明,让调用者去处理。关键字 throws 运用于方法声明上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。

    声明异常语法: 修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2...{}

    throws 用于进行异常的声明,若该方法可能有多种异常情况产生,那么在 throws 后面可以写多个异常类,用逗号隔开。最大的异常习惯放后面。

    异常处理两种方式

    如果异常出现的话,会立刻终止程序,所以我们得处理异常:

    1. 声明异常:throws该方法不处理,而是声明可能出现的异常,将问题暴露给调用者,让调用者自己处理!

    2. 捕获异常:try catch 在方法中使用try-catch的语句块直接处理可能出现的异常!

     1  package com.exception;
     2  public class Test2 {
     3      public static void main(String[] args) {
     4          try {
     5              new Test2().test(1,0);
     6          }catch(ArithmeticException e){
     7              e.printStackTrace();
     8          }
     9      }
    10      //假设这方法中,处理不了这个异常。方法上抛出异常
    11      public void test(int a,int b){
    12          if(b==0){//throw throws
    13              throw new ArithmeticException();//主动的抛出异常,一般在方法中使用
    14          }
    15      }
    16  }

    异常注意事项

    多个一擦汗给你使用捕获又该如何处理?

    1. 多个异常分别处理。

    2. 多个异常一次捕获,多次处理。

    3. 多个异常一次捕获一次处理。

    一般我们使用一次捕获多次处理的方法,格式如下:

    1 try{
    2     //可能出现异常的代码
    3 }catch(异常类型A e){//当 try 中出现A类型异常,就用该catch来捕获
    4     //处理异常的代码
    5     //记录日记/打印异常信息/继续抛出异常
    6 }catch(异常类型B e){//当 try 中出现B类型异常,就用该catch来捕获
    7     //处理异常的代码
    8     //记录日记/打印异常信息/继续抛出异常
    9 }

    注意:这种处理方式,要求多个catch中的异常不相同,并且若catch中的多个异常之间有子夫类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。

    • 运行时异常被抛出可以不处理,即不捕获也不声明抛出。

    • 如果finally有return语句,永远返回finally中的结果,避免该情况。

    • 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。

    • 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出。(throws)

    自定义异常

    在开发中根据自己业务的异常情况来定义异常类:

    例如 自定义一个业务逻辑异常:PasswordErrorException。密码错误类。

    异常类如何自定义:

    1. 自定义一个检查异常:自定义类 并继承于 java.lang.Exception

    2. 自定义一个运行时期的异常类:自定义类 并继承于 java.lang.RuntimeException

     1 public static void main(String[] args) {
     2         UserService ser =new UserService();
     3         try {
     4             //异常可以处理,也可以不处理:运行时异常
     5             boolean res1=ser.validateName("test1");
     6             System.out.println(res1);
     7         } catch (UserNameIsNotExistException e) {
     8             e.printStackTrace();
     9         }
    10         try {
    11             //必须处理异常:有可能是检查异常
    12             boolean res=ser.login("teset1","teset");
    13             System.out.println(res);
    14         } catch (UserPwdErrorException e) {
    15             e.printStackTrace();
    16         }
    17     }
     1 public class UserService {
     2     public boolean validateName(String name) {
     3         if(!name.equals("test")) {
     4             throw new UserNameIsNotExistException();
     5         }else {
     6             return true;
     7         }
     8     }
     9     public boolean login(String name,String pwd) throws UserPwdErrorException{
    10         if(name.equals(pwd)) {
    11             return true;
    12         }else {
    13             throw new UserPwdErrorException();
    14         }
    15     }
    16 }
    1 public class UserNameIsNotExistException extends RuntimeException{
    2     public UserNameIsNotExistException() {
    3         super("用户名不存在!");
    4     }
    5 }
    1 public class UserPwdErrorException extends Exception{
    2     public UserPwdErrorException() {
    3         super("用户名或密码错误!");
    4     }
    5 }
  • 相关阅读:
    C语言之回调函数&模块化
    680. 验证回文字符串 Ⅱ
    C++指针数组和数组指针
    345. 反转字符串中的元音字母
    633.平方数之和
    IDM使用介绍篇
    路由器无线桥接WDS
    约数的个数
    密码翻译
    查找学生信息
  • 原文地址:https://www.cnblogs.com/d-java/p/13065945.html
Copyright © 2020-2023  润新知