前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础——异常

Java基础——异常

作者头像
羊羽shine
发布2019-05-28 13:34:41
5250
发布2019-05-28 13:34:41
举报
文章被收录于专栏:Golang开发Golang开发
概述

在运行的时候发生不正常的情况。在Java中采用类的形式对异常问题进行描述和封装对象。

image.png

对比Exception和Error Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。 Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。 Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常 见的比如 OutOfMemoryError 之类,都是 Error 的子类。 Throwable中的常用方法:

- public void printStackTrace():打印异常的详细信息。
  包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
- public String getMessage():获取发生异常的原因。
  提示给用户的时候,就提示错误原因。
- public String toString():获取异常的类型和异常描述信息(不用)。
异常分类

可检查(checked)异常, 可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。前面介绍的不可查的 Error ,是 Throwable 不是 Exception 。 不检查 (unchecked)异常 不检查异常就是所谓的运行时异常,类似 NullPointerException ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。

image.png

try-catch代码段会产生额外的性能开销,或者换个角度说,它往往会影响JVM对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的try包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句( if/else 、 switch )要低效。 Java每实例化一个Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。 所以,对于部分追求极致性能的底层类库,有种方式是尝试创建不进行栈快照的 Exception 。这本身也存在争议,因为这样做的假设在于,我创建异常时知道未来是否需要堆栈。问 题是,实际上可能吗?小范围或许可能,但是在大规模项目中,这么做可能不是个理智的选择。如果需要堆栈,但又没有收集这些信息,在复杂情况下,尤其是类似微服务这种分布 式系统,这会大大增加诊断的难度。

常见异常

1、NullPointerException 空指针异常,操作一个 null 对象的方法或属性时会抛出这个异常。

public static void main(String[] args) {
        int[] arr = null;
        System.out.println(arr[1]);

    }

2、OutOfMemoryError

内存异常异常,这不是程序能控制的,是指要分配的对象的内存超出了当前最大的堆内存,需要调整堆内存大小(-Xmx)以及优化程序。 3、IOException IO,即:input, output,我们在读写磁盘文件、网络内容的时候经常会生的一种异常,这种异常是受检查异常,需要进行手工捕获。

如文件读写会抛出 IOException:

public int read() throws IOExceptionpublic void write(int b) throws IOException

4、FileNotFoundException

文件找不到异常,如果文件不存在就会抛出这种异常。如定义输入输出文件流,文件不存在会报错,FileNotFoundException 其实是 IOException 的子类,同样是受检查异常,需要进行手工捕获。

5、ClassNotFoundException

类找不到异常,Java开发中经常遇到,是不是很绝望?这是在加载类的时候抛出来的,即在类路径下不能加载指定的类。看一个示例:

它是受检查异常,需要进行手工捕获。 ** 6、ClassCastException** 类转换异常,将一个不是该类的实例转换成这个类就会抛出这个异常。 如将一个数字强制转换成字符串就会报这个异常:

 public static void main(String[] args) {
        Object  a  = 1;
        String s = (String) a;
        System.out.println(s);

    }

这是运行时异常,不需要手工捕获。 7、NoSuchMethodException 没有这个方法异常,一般发生在反射调用方法的时候 8、IndexOutOfBoundsException 越界异常 索引越界异常,当操作一个字符串或者数组的时候经常遇到的异常。

public static void main(String[] args) {
        int[] arr = {1,2,3,4};
        System.out.println(arr[4]);

    }

** 9、ArithmeticException** 算术异常,发生在数字的算术运算时的异常,如一个数字除以 0 就会报这个错。

double n = 3 / 0;

10、SQLException SQL异常,发生在操作数据库时的异常。 如下面的获取连接: 又或者是获取下一条记录的时候:

boolean next() throws SQLException;

它是受检查异常,需要进行手工捕获。

异常处理

捕获异常try...catch...finally

捕获异常语法格式如下,try和catch都不能单独使用,必须连用。finally是可选性

try{
      可能出现异常代码
}catch(Exception e){
    处理异常的代码
}finally{
    一定会执行的代码
}

eg:

public static void main(String[] args) {
        try{
            int a = 2/0;
        }catch (ArithmeticException e){
            System.out.println("除数不能为0");
        }
    }

多个错误的处理

 public static void main(String[] args) {
        try {
            int[] arr = {1,2,3,4};
            System.out.println(arr[4]);//ArrayIndexOutOfBoundsException数组越界异常
            int a = 2 / 0;//ArithmeticException:算术异常
            System.out.println(a);
            int[] arr1 = null;
            System.out.println(arr1[0]);//NullPointerException空指针
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常...");
        } catch (ArithmeticException e){
            System.out.println("算术异常...");
        } catch(NullPointerException e){
            System.out.println("空指针异常...");
        }

    }

多个异常通过|连接

 try {
          
        } catch (ArrayIndexOutOfBoundsException |ArithmeticException | NullPointerException e) {
            System.out.println(e.getClass());
        }

finaly和return

public static void main(String[] args) {
        System.out.println(divFun(2,0));
    }

    public static int  divFun(int a,int b){
        int result = 0;
        try {
            result = a/b;
        } catch (Exception e) {
            System.out.println(e.getClass());
            result = -1;
            return result;
        }finally {
            System.out.println("finally action");
        }
        return result;
    }
声明异常throws

使用throws声明的方法表示此方法不处理异常,抛给方法的调用者处理,用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开。关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).

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

eg

    public static void main(String[] args) {
        try {
            System.out.println(divFun(2,0));
        }catch (Exception e){
            System.out.println(e);
        }
    }

    public static int divFun(int a,int b) throws ArithmeticException{
        int result = a/b;
        return result;
    }

它表示抛出异常,由该方法的调用者来处理

抛出异常throw

用在方法体内,跟的是异常对象名,抛出的时候直接抛出异常类的实例对象。将这个异常对象传递到调用者处,并结束当前方法的执行。

throw new 异常类名(参数);

eg:

public static int divFun(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException();
        }
        int result = a / b;
        return result;
    }
自定义异常

自定义异常直接继承Exception就可以完成自定义异常类

public static int divFun(int a, int b) throws ZeroException {
        if (b == 0) {
            throw new ZeroException("除数不能为0");
        }
        int result = a / b;
        return result;
    }
class ZeroException extends Exception{
    public ZeroException(String message){
        super(message);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.03.02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 异常分类
  • 常见异常
  • 异常处理
    • 捕获异常try...catch...finally
      • 声明异常throws
        • 抛出异常throw
          • 自定义异常
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档