暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Java异常

Hello 帅帅 2021-02-05
592

异常类

异常概念

  • 异常指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

  • 在Java中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。

  • Java处理异常的方式是中断处理。

异常体系

异常分类

Throwable共有两个子类:

  • Error:严重错误,无法处理。如内存溢出,系统崩溃。

  • Exception:异常,可进行处理分为两种

    • 运行时异常:都是RuntimeException
      类及其子类异常,如NullPointerException
      (空指针异常)、IndexOutOfBoundsException
      (下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch
      语句捕获它,也没有用throws
      子句声明抛出它,也会编译通过。

    • 非运行时异常(编译异常):RuntimeException
      以外的异常,类型上都属于Exception
      类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如日期格式化异常,IOException
      SQLException
      等以及用户自定义的Exception
      异常,一般情况下不自定义检查异常。

打印异常

异常过程解析

package com.company;
public class MyException1 {
   public static void main(String[] args) {
       int[] a = {0, 1, 2};
       int doing = ArrayTools.doing(a, 3);
       System.out.println(doing);
  }
}

class ArrayTools {
   public static int doing(int[] arr, int i) {
       return arr[i];
  }

}

异常处理

try…catch…finally

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

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

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

示例代码:

public class MyException2 {
   public static void main(String[] args) {
       try{
           int a=1/0;
      }catch (ArithmeticException e){
           System.out.println(e.toString());
      }finally {
           System.out.println("bye-bye");
      }
  }
}

输出:

java.lang.ArithmeticException:  by zero
bye-bye

如何获取异常信息:

Throwable类中定义了一些查看方法:

  • public String getMessage()
    :获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。

  • public String toString()
    :获取异常的类型和异常描述信息(不用)。

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

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

throw

示例代码:

public class MyException2 {
   public static void main(String[] args) {
       int a = -10;
       if (a < 0) {
           throw new ArithmeticException("a不能小于0");
      } else {
           System.out.println(a);
      }
  }
}

输出:

Exception in thread "main" java.lang.ArithmeticException: a不能小于0
at com.company.MyException2.main(MyException2.java:9)

如果a<0则抛出异常,否则打印a

throws

声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。

关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).

声明异常格式:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{   }

声明异常的代码演示:

public class MyException2 {
   public static void main(String[] args) {
       String s = "file1.txt";
       try {
           demo1(s);
      } catch (IOException e) {
           e.printStackTrace();
      }
  }

   private static void demo1(String a) throws IOException {
       if (!"file.txt".equals(a)) {
           throw new IOException("文件不存在");
      } else {
           System.out.println(a);
      }
  }
}

输出:

java.io.IOException: 文件不存在
at com.company.MyException2.demo1(MyException2.java:17)
at com.company.MyException2.main(MyException2.java:9)

注:

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

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

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

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

  5. 多个异常使用捕获又该如何处理呢?

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

    try{
        编写可能会出现异常的代码
    }catch(异常类型A  e){  当try中出现A类型异常,就用该catch来捕获.
        处理异常的代码
        //记录日志/打印异常信息/继续抛出异常
    }catch(异常类型B  e){  当try中出现B类型异常,就用该catch来捕获.
        处理异常的代码
        //记录日志/打印异常信息/继续抛出异常
    }

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

    1. 多个异常分别处理。

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

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

自定义异常类

实际开发中也会出现很多异常,这些异常很可能在JDK中没有定义过,这时需要我们自己去定义。

异常类如何定义:

  1. 自定义编译期异常:自定义类继承于java.lang.Exception

  2. 自定义运行时异常:自定义类继承于java.lang.RuntimeException

Student:

public class Student {
   private String sex;

   public void setSex(String sex) throws Exception {
       if ("男".equals(sex) || "女".equals(sex)) {
           this.sex = sex;
      } else {
           throw new GendorException("性别必须是男或者女");
      }
  }
}

Test:

public class Test {
   public static void main(String[] args) {
       Student p = new Student();
       try {
           p.setSex("不知道");
      } catch (Exception e) {
           System.out.println("设置性别出错了");
           e.printStackTrace();//输出异常信息
      }
  }
}

GendorException:

public class GendorException extends Exception {
   public GendorException(String msg) {
       super(msg);
  }
}

输出:

设置性别出错了
com.company.GendorException: 性别必须是男或者女
at com.company.Student.setSex(Student.java:17)
at com.company.Test.main(Test.java:9)



文章转载自Hello 帅帅,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论