关于Java中异常的讨论

9 篇文章 0 订阅
2 篇文章 0 订阅
导言

异常(Exception)类是Java中一个族系的大类,这些类往往来处理我们程序编写、编译或者运行时可能出现的问题。Java的异常机制原则上是要增强程序的健壮性,通过对语法的检测和风险的预测来避免一些人为的错误。但是实际上避免异常的最好办法就是我们编写代码时要尽量避免出现错误和在运行的时候尽量正确的进行IO操作,或者更好的引导使用者规范自己的操作来避免这些异常。但是既然Java提供了异常类这一大类,我们就要从形到意去掌握它。

异常的分类

在Java中异常类是所有错误或异常的超类Throwable类的子类,与它同级的子类Error一般来处理系统级别的内存错误。但是异常一般是潜在的错误操作会带来的程序终止或者报错等的统称。
异常分为运行时异常和编译时异常。运行时异常(RuntimeException)通常包括算法错误,空指针错误,数组越界等等这些在语法上正确但是不符合逻辑的错误,一般能通过编译,会在运行时被捕获异常。
编译时的异常一般在语法上存在错误,比如类型不匹配,IO流操作异常,文件丢失等等……一般来说IDE会在编译时对这些异常进行捕获提醒。在编译类异常中IOException类异常往往是我们经常会遇到和用到的异常类。
Exception

JVM是如何处理异常的?

我们知道JVM通过调用main方法来进入程序,所以当main函数中存在异常时,JVM默认机制是创建一个可以接收异常信息的类,然后将捕获的异常信息打印到控制台上,然后终止当前程序的运行。通常我们不建议将异常抛到JVM中,因为JVM在捕获异常后会强制终止程序,如果异常在程序的前面或中间,往往大部分主题的代码是没有被执行的,这往往与我们的目的是相悖的。所以JVM对异常的处理机制往往是一种提醒,我们更多的是在程序中去解决异常。

从除0来接触异常

我们编写一个简单的方法,通过传入一个除数一个被除数来计算它们的数,我们来看看代码是什么样的:

public class ExceptionDemo {
    public static void main(String[] args) {
        divsionMethod(10,0);
    }

    public static int divsionMethod(int dividend, int divisor){
        return dividend/divisor;
    }
}

运行时出现了:Exception in thread “main” java.lang.ArithmeticException: / by zero这里的ArithmeticException意思是JVM捕获了一个算法的异常,/ by zero说明这个错误时由于0引起的异常。这里我们的代码在编译的时候是没有出现错误的,所以这是一个运行时的异常。那么要怎么解决这个异常呢?解决异常一般有两种办法:

方法一:抛出去

在Java中有一个关键字throws,它的作用就是定义在方法名的后面来抛出这个方法里的异常给后面调用或者创建它对象的类或者方法:
格式为:方法名() throws 异常类名
除了throws还有一个使用在方法体内部的关键字throw,它一般抛出的是异常类的对象,构造方法一般是处理语句。
格式为:throw new Exception(“处理语句”);
我们使用这这方法来处理一下上述的异常代码:

public class ExceptionDemo {
    public static void main(String[] args) throws ArithmeticException{
        divsionMethod(10,0);
    }

    public static int divsionMethod(int dividend, int divisor) throws ArithmeticException{
        return dividend/divisor;
    }
}

上述代码中我们首先看到了divisionMethod方法将异常抛出,然后调用它的main方法发现这个异常我已然解决不了,同样使用throws关键字抛出,我们知道运行时mian方法会被JVM调用,所以最后JVM捕获了这个异常并且做了处理,终止了程序并且在控制台上打印了异常信息。
但是这样的处理是好的么?我其实十分不建议这样去处理异常,因为将异常一层层抛给JVM后往往JVM只会输出异常的信息,而且最关键的是JVM捕获异常会强行终端程序的运行,所以我们最好的方式就是自己去处理异常。那么我们的第二种方法就是要来自己处理它。

方法二:try catch finally

我们既然不能不管不顾的只是抛出这些异常,我们最好对这些异常进行处理,这一就提到了try catch finally关键字。这三个关键字往往是同时出现的。所以我们首先介绍他们的用法。

public static void fileRead(){
        try {
            FileInputStream fis = new FileInputStream("D:\\text.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();//java.io.FileNotFoundException: D:\text.txt (系统找不到指定的文件。)
                                // at java.io.FileInputStream.open0(Native Method)......
            e.toString();//java.io.FileNotFoundException: D:\text.txt (系统找不到指定的文件。)
            e.getMessage();//D:\text.txt (系统找不到指定的文件。)
        } finally {
            System.out.println("程序结束");
            fis.close();
        }
    }

运行结果:

程序结束
java.io.FileNotFoundException: D:\text.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at ExceptionDemo.fileRead(ExceptionDemo.java:16)
    at ExceptionDemo.main(ExceptionDemo.java:7)

首先来解释这个方法,这个方法是从硬盘上读入一个文本文件的文本信息到输入流中,我们没有在方法上抛出异常便通过了编译,所以这里的异常是一个非运行时的异常(编译期异常)。实际上我们硬盘上并没有这个文件,所以我们需要在遇到这种情况时处理这种异常,所以我们在try关键字中包括了可能出现异常的代码,当异常出现时,我们需要捕获它并且创建一个接受异常信息的对象。所以紧接着有了catch关键字,catch关键字传入一个异常类的对象为参数,这里catch方法体内便是捕获异常时我们要做的处理。一般来说我们会输出异常的信息。
默认情况下e.printStackTrace()是输出错误完整信息,包括异常类型,错误提示信息和错误出现位置
e.toString()只输出错误提示信息
e.getMessage()输出错误提示信息和异常类信息
其中e.toString()和e.getMessage()两个方法均返回的是String类型的字符串,所以要打印到控制台一般要通过print语句带实现。
最后就是finally里的东西了,我们运行结果的时候,在报异常终止前finally里的东西是执行过的,所以这里就可以验证finally里的东西就是不受异常影响一定可以执行的东西。它的用处一般是来释放输入输出流来节省系统资源的。

异常的扩展:自定义异常

这个东西我们在基础学习阶段是很难用到的,因为系统已经提供了丰富的异常类来处理我们日常写代码时会出现的异常,但是如果在实际工作中,大的系统和项目或者复杂的算法可能需要一些特殊的异常处理,系统没有预定义,我们就要自己去写这些异常的类,这就是自定义的异常。由于异常都是类实现,所以不难相处自定义的异常也是通过继承基础的异常类(Exception)来重写printStackTrace()方法和检测方法实现的,这里只给出了模版,具体的方法大家在输入研究时或许会学习:

class DemoException extends Exception{
    @Override
    .....//重写方法和检测方法等等
}
总结

异常是帮助开发的人知道错误的详细信息 从而修改过来 。但是异常其实不知是用来提示错误信息的。当一个庞大的程序中一个小地方出现异常时,我们通过异常的解决可以避免程序的终止导致其他问题。异常作为一种检测代码隐含错误的一种方法,有经验的程序员也会经常去使用try catch的方法来寻找代码中的错误。掌握好异常我们才能从容处理编程过程中经常会出现的错误,让代码更加健壮完整!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值