day22_ 异常 throw throws try..catch.. finally

今日内容

  • 异常

异常:

 异常的根类是java. lang . Throwable,其下有两个子类分别是:java . lang .Error 和 java . lang. Exception.

 Error是错误,不可通过异常处理的错误,就好比人体的艾滋病,癌症等,只能是事先预防

 今天主要是说Exception(编译期异常):异常。是可以通过代码的方式进行修改纠正,然后可以继续进行下去。好比人的感冒等

  Exception的RuntimeException(运行期异常)包括常见的:

ArrayIndexOutOfBoundsException:  索引越界异常

其中有5个关键字:throw , throws , try   catch , finally

  throw:抛出异常

  编写程序的时候程序可能会出现问题,可以使用throw关键字在指定的方法中抛出指定的异常

  使用格式:

throw new XxxException("异常产生的原因");

  注意:

  1.throw关键字写在方法的内部。

  2.throw关键字后面必须是Exception或者Exception的子类对象

  3.throw关键字抛出指定的异常对象后。我们就必须去处理这个异常对

    throw关键字后面创建的是RuntimeException或者RuntimeException的子类对象,我们可以选择不处理,交给(打印异常对象,)

    throw关键字后面创建的是编译异常(写代码的时候就会出现的问题),我们就必须处理这个异常,要么是throws,要么使用try。。。catch

public static void main(String[] args) {
    int[] arr = null;
    int a =  get(arr, 2);
    System.out.println(a);//
}    
    public static int get(int[] arr,int index){
        if (arr==null) {
            //
            throw new NullPointerException("传递的数组值为null");
        }        
        return arr[index];
    }
}

 

  throws关键字

    异常处理的第一种方式:声明异常处理,将异常交给方法的调用者来处理

    当方法内部抛出了异常,我们必须处理这个异常对象,这个方法把异常对象抛给方法的调用者,调用者再网上抛,最终教给虚拟机,虚拟机中断处理

  格式:

    修饰符  返回值类型  方法名(参数列表)  throws  XxxException,ZzzException...{

      throw new XxxException("产生的原因");
      throw new ZzzException("产生的原因");
        ......
}

    注意:

    1.throws 关键字必须写在方法声明处。

    2.throws 关健字后面声明的异常必须是Exception或者是Exception的子类

    3.方法内部如果抛出了多个异常对象,那么throws后面也必须声明对应的多个异常,如果抛出的多个异常对象有父子类关系的时候,可以直接声明父类类型即可

    4.调用了一个声明抛出异常的方法(通过throw方法抛出),我们就必须处理这个异常声明,要么继续throws抛出,要么使用try...catch处理

 备注:异常到哪一个,就终止在哪。   

public static void main(String[] args) throws FileNotFoundException, TimeoutException {
        
    String pString ="C:\\abc.txt" ;
     haha(pString);
    
    System.out.println( "keyi ");        
}    
public static void haha(String pString) throws FileNotFoundException, TimeoutException{
    if (!pString.endsWith("txt")) {
        throw new FileNotFoundException("不是txt");
    }
    if (!pString.startsWith("C:")) {
        throw new TimeoutException("不是C盘");
    }
    
}

Objects非空判断

  该类中提供了静态方法,null - save(空指针安全)或者null- tolerant(容忍空指针)。在他的源码中,对对象的null值进行了抛出异常的操作

public static <T> T  requireNonNull(T obj){
    if(obj == null)
      throw new NullPointerException();
     return obj;
}

捕获异常try...catch

自己处理异常

  如果异常出现的话,会立即终止程序。两种方法

  1.上述throws声明处理,危险

  2.方法中使用try...catch的语句块来处理异常

try .... catch的方式是捕获异常

  捕获异常的方式:可以对出现的异常指定方式捕获;

格式:

try{
    //编写的可能会出现异常的代码
    //.....
}catch(异常类型  c){
       //处理异常的逻辑代码
//一般在工作中,会把异常的信息记录到日志中
}

其中try:该语句块中可能出现异常的代码

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

备注:try和catch都不能单独使用,一般建议连用

演示:

 

Thowable类中定义了一些常用的api方法

  public String getMessage()获取异常的描述信息,原因(提示给用户看的,提示错误原因);

  public String toString();获取异常的类型,异常的描述信息

  public void printStackTrace(): 打印异常的跟踪栈信息并输出到控制台中

这包含了异常的类型,原因,出现的位置。开发和调试阶段一般都适用

  Finally语句块

  finally: 有一些特殊代码无论异常是否发生,都需要执行,当程序发生异常时,会引发程序的跳跃性,finally语句块中的代码是一定会被执行到的。

  格式:

try{
//
}catch(异常类型  e){
     //...          
}
...
}finally{
//...
}

备注:中间的catch语句块可以不省略,finally不能单独使用,建议连用

注意事项:

1.finally不能单独使用,必须和try一起使用

2.finally语句块一般用于资源的释放,(资源回收),无论程序是否出现异常,最后都要加载finally语句块中的内容,都要释放资源

备注:

  如果finally语句块中有return语句,永远返回的是finally语句块中的结果值。

  当只要在try或者catch中调用退出JVM的相关方法,此时finally才不会被执行到,否则finally永远会执行

 

异常的注意事项

  程序中出现多个异常

  1.多个异常分别处理

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

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

一般用的是一次捕获,多次处理,格式如下:

try{
//可能出现异常的代码  多个异常
}catch(异常A){//当try中出现A异常的时候,就用该catch来捕获
//处理异常的逻辑
}catch(异常B){//当try中出现B异常的时候,就用该catch来捕获
//处理异常的逻辑
}
....
...

要求catch多个异常不能相同,异常之间有父子关系,子类处理在上,父类在下。

 

  • 运行时异常被抛出可以不处理,即不捕获也不声明抛出
  • 如果finally中有return语句,那么永远返回finally语句块中的结果值
  • 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
  • 父类方法如果没有抛出异常,子类重写该方法时,也不可能抛出。此时如果子类方法内产生了异常,只能捕获处理,不能声明抛出。

自定义异常

概述:

  出去官方提供的异常外,还要自定义的异常类。例如:年龄负数,成绩负数,登录异常等等

异常类定义:

  • 自定义一个编译期异常,自定义类继承于java.lang.Exception。
  • 自定义一个运行期异常类,自定义类继承与java.lang.RuntimeException。

 例子:

//自定义异常类步骤
//1.定义一个异常类  类继承系统给定的异常类
public class ExceptionDemo01 extends Exception {
    // 空参构造
    public ExceptionDemo01() {
    }
    // 全参 参数设置为传输的字符串
    public ExceptionDemo01(String a) {
        super(a);
    }
}


public class Application {
    // 成员静态变量设置
    public static String[] name = { "小孙", "小王", "小丽", "小张" };
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String names = sc.next();
        // 3.try...catch
        try {
            // 方法调用,有参数的话要传参数
            nemeDemo(names);
            System.out.println("名字可以,万里挑一");
            // ()里面是异常类名 e是给方法生成名字
        } catch (ExceptionDemo01 e) {
            // 调用输出方法三种
            e.printStackTrace();// 直接打印异常所有信息
            System.out.println(e.getMessage());// 显示内容及类型
            System.out.println(e.toString());// 只显示内容
        }
    }
    // 2.做一个方法遍历检查
    public static void nemeDemo(String uname) throws ExceptionDemo01 {
        // for遍历
        for (String string : name) {
            if (string.equals(uname)) {
                // 格式: throw+new +异常类名(参数传输字符串)
                throw new ExceptionDemo01("名字没了你妹的");
            }
        }
    }

}

 

 

  

posted @ 2020-12-10 20:57  wajueji  阅读(93)  评论(0编辑  收藏  举报