资讯专栏INFORMATION COLUMN

#Java异常处理

nidaye / 1524人阅读

摘要:例子二以下开始用异常处理机制捕获该异常在这里,这个其实就是这里用到了程序运行时的多态思想。语句就像一个调用函数,当程序运行中抛出了一个异常对象,就会调用对应的来处理。

传统的语言如何处理

在一些传统的语言(如C语言中)

if语句来判断是否出现了例外

全程变量ErrNo

但这有几个缺点

正常处理与异常处理的代码同样处理

可读性(readability)差

每次调用一个方法时都进行错误检查

可维护性( maintainability )差错误由谁处理不请

职责不清

Java中的异常处理特点:

Java中处理异常包括

抛出(throw)异常

运行时系统在调用栈中查找

从生成异常的方法开始进行回溯,直到找到:

捕获(catch) 异常的代码
调用过程如下所示:

代码 例子一

没有使用Java异常处理机制

public class Test {
    public static void main(String [] args){
        for(int i = 0; i < 2;i++){
            System.out.print(i + " ");
            System.out.println(1/0);//throw an exception.
        }
    }
}

运行结果:

0 Exception in thread "main" java.lang.ArithmeticException: / by zero

1/0明显非法,所以产生了异常ArithmeticException对象,这个对象是Exception的子类。

例子二

以下开始用异常处理机制捕获该异常:

public class Test {
    public static void main(String [] args){
        for(int i = 0; i < 2;i++){
            System.out.print(i + " ");
            try{
                System.out.println(1/0);//An exception will throw from here.
            }
            catch(Exception ex){//在这里,这个Exception 其实就是ArithmeticException
            //这里用到了程序运行时的多态思想。
            //实际中应指定具体的作为ex的类型,更加有针对性。
                System.out.println("exception handling...");//
            }
        }
    }
}

运行结果:

0 exception handling...
1 exception handling...

这样确实能捕获到相应的异常对象。尽管什么也没做(只是打印字符串),却让编译器不再报告之前的异常。因为上述catch(type ex){...}就是负责处理异常。

例子三

当捕获到异常后,程序的运行过程会怎样?

public class Test2 {
    public static void main(String[] args){
        try{
            for (int i = 0; i< 2; i++){
                System.out.print(i + " ");
                System.out.println(1/0);//exception being thrown from here.Then it wil jump directly to the corresponding catch block.
                System.out.println("This line is supposed to be ignored");
            }
        }
        //handling the exception.
        catch(Exception ex){
            System.out.println("Exception handling...");
        }
        System.out.println("End of the main()");
    }
}

运行结果:

0 exception handling...
End of the main()

for不可能循环到i = 2;因为在i = 1时已经抛出了异常。只要产生了异常,转入对应的catch(type ex){...}catch(type ex)必须在参数里面说明捕获的对象是哪类型的。
throw语句就像一个调用函数,当程序运行中抛出了一个异常对象,就会调用对应的catch(type ex){}来处理。但它又不像调用函数。因为在调用完后,它不会返回到throw语句,而是接着catch之后的语句。所以System.out.println("This line is supposed to be ignored");这条语句被没有执行;for循环也相当于被中断了。

Java的异常处理语句

抛出异常

throw 异常对象;

捕获异常

try{
    语句组
}
catch(异常类名 异常形式参数名){
    异常处理语句组; 
}
catch(异常类名 异常形式参数名){
    异常处理语句组; 
}
finally{
    异常处理语句组;
}

其中,catch语句可以0至多个,可以没有finally语句

异常的分类

Throwable

Error: JVM的错误(一般来说,我们很难处理这里异常)

Exception: 异常(重点关注)
注:一般所说的异常,是指Exception及其子类

Exception类

构造方法

public Exception();
public Exception(String message);
Exception(String message, Throwable cause) ;

方法

getMessage()
getCause()
printStackTrace()
代码 例子一

仍然是没有使用Java的异常处理机制:

import java.util.Scanner;
public class QuotientWithMethod {
    public static int quotient(int num1, int num2){
        if(num2 == 0){
            log("Divisor cannot be zero");
            System.exit(1);
        }
        return num1/num2;
    }
    public static void log(String s){
        System.out.println(s);
    }
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        //prompt user to enter two integers
        int num1 = input.nextInt();
        int num2 = input.nextInt();
        int result = quotient(num1,num2);//调用函数
        System.out.println(num1 + "/" + num2 + "is" + result );
    }
}

运行结果

input two numbers:
1 0
Divisor cannot be zero

在没用使用异常处理机制的情况下,出现了异常情况的话,在被调用的函数中,处理异常情况——这里是直接退出了程序;

例子二

用异常处理机制的好处是职责分明:被调函数中抛出异常,主调函数中负责处理异常。

import java.util.Scanner;
public class QuotientWithException {
    public static int  quotient(int num1, int num2){
        if(num2 == 0){
            throw new ArithmeticException("Divisor cannot be zero");//用关键字throw抛出异常对象,这里是调用构造器来新建对象
        }//但不做处理
        return num1/num2;
    }
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        System.out.println("input two numbers:");
        int num1 = input.nextInt();
        int num2 = input.nextInt();
        boolean goOn = true;
        do {
            try {
                int result = quotient(num1, num2);
                System.out.println("num1" +"/" + "num2" + "is" +result);
                goOn = false;
            }
            //职责分明;一个负责抛出异常,一个负责处理异常.
            catch(ArithmeticException ex){
                //在主调函数中处理异常
                System.out.println("Exception occur:" + "Divisor cannot be zero. 
 input again,please:");
                num1 = input.nextInt();
                num2 = input.nextInt();
                //int result = quotient(num1, num2);
                //System.out.println("num1" +"/" + "num2" + "is" +result);
            }
        }while(goOn);
        //处理后,进入catch{}后的语句.
        System.out.println("End of main().");
    }
}

运行结果

input two numbers:
1 0
Exception occur:Divisor cannot be zero. 
 input again,please:
1 1
num1/num2is1
End of main().

在被调函数中,只负责抛出异常:throw new ArithmeticException("Divisor cannot be zero");,主调函数中catch(ArithmeticException ex){...}指定将要捕获的对象的类型,并做相应的处理,这里要求重新输入。

多异常的处理

子类异常要排在父类异常的前面,也就是先处理具体的异常,后处理抽象的异常。

finally语句,无论是否有异常都要执行,即使其中有break,return等语句

在编译时,finally部分代码生成了多遍

Exception分两种

RuntimeException及其子类,可以不明确处理;否则,称为受检的异常(checked Exception)

RuntimeException, Error, and their subclasses are known as unchecked exceptions. All other exceptions are known as checked exceptions, meaning that the compiler forces the programmer to check and deal with them in a try-catch block or declare it in the method header.--Introduction to Java

对于受检的异常(checked Exception),要求明确进行语法处理:

要么捕(catch)

要么抛(throws):在方法的签名后面用throws xxxx来声明

在子类中,如果要覆盖父类的一个方法,若父类中的方法声明了 throws异常,则子类的方法也可以throws异常

可以抛出子类异常(更具体的异常),但不能抛出更一般的异常

自定义异常类

创建用户自定义异常时

继承自Exception类或某个子Exception类

定义属性和方法,或重载父类的方法

这样getMessage(), toString(), printStackTrace()都会从Exception继承下来。

重抛异常及异常链接( Chained Exceptions)

对于异常,不仅要进行捕获处理,有时候还需要将此异常进一步传递给调用者,以 便让调用者也能感受到这种异常。这时可以在catch语句块或finally语句块中采取,以下三种方式:

将当前捕获的异常再次抛出:
throw e;

重新生成一个异常,并抛出,如:
throw new Exception("some message");

重新生成并抛出一个新异常,该异常中包含了当前异常的信息,如:throw new Exception("some message",e);e.getCause() 来得到内部异常

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65915.html

相关文章

  • 16.java异常处理

    摘要:不受检查异常为编译器不要求强制处理的异常,检查异常则是编译器要求必须处置的异常。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。异常处理涉及到五个关键字,分别是。 概念 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。 异常是程序中的一些错误,但并不是所有的错误都是异常,并...

    asce1885 评论0 收藏0
  • Java异常处理

    摘要:异常也就是指程序运行时发生错误,而异常处理就是对这些错误进行处理和控制。有两个重要的子类异常和错误,二者都是异常处理的重要子类,各自都包含大量子类。需要注意的是,一旦某个捕获到匹配的异常类型,将进入异常处理代码。 1,异常现象 程序错误分为三种:1,编译错误;2,运行时错误;3,逻辑错误。 编译错误是因为程序没有遵循语法规则,编译程序能够自己发现并且提示我们错误的原因和位置,这...

    CarlBenjamin 评论0 收藏0
  • Java异常处理

    摘要:可以被异常处理机制使用,是异常处理的核心。非检测异常,在编译时,不会提示和发现异常的存在,不强制要求程序员处理这样的异常。总体来说,语言的异常处理流程,从程序中获取异常信息。处理运行时异常,采用逻辑合理规避同时辅助处理。 目录 什么是Java异常? 当一个Exception在程序中发生的时候,JVM是怎么做的呢? 当我们编写程序的时候如何对待可能出现的异常呢? 正文 1. 什么是J...

    Fourierr 评论0 收藏0
  • Java 异常处理

    摘要:下面是异常处理机制的语法结构业务实现代码输入不合法如果执行块里业务逻辑代码时出现异常,系统自动生成一个异常对象,该对象被提交给运行时环境,这个过程被称为抛出异常。 Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字, try关键字后紧跟一个花括号括起来的代码块(花括号不可省略),简称try块,它里面放置可能引发异常的代码 catch后对...

    senntyou 评论0 收藏0
  • java异常处理机制的理解

    摘要:根据异常对象判断是否存在异常处理。否则,范围小的异常会因异常处理完成而无法处理。异常处理中使用作为异常的统一出口。 参考《第一行代码java》《java程序设计教程》java中程序的错误有语法错误、语义错误。如果是语法性错误,在编译时就可以检查出来并解决。语义错误是在程序运行时出现的,在编译时没有错误,但在运行时可能会出现错误导致程序退出,这些错误称为异常。在没有异常处理的情况下,也即...

    khs1994 评论0 收藏0
  • Java异常处理 10 个最佳实践

    摘要:为可恢复的错误使用检查型异常,为编程错误使用非检查型错误。检查型异常保证你对错误条件提供异常处理代码,这是一种从语言到强制你编写健壮的代码的一种方式,但同时会引入大量杂乱的代码并导致其不可读。在编程中选择检查型异常还是运行时异常。 异常处理是Java 开发中的一个重要部分。它是关乎每个应用的一个非功能性需求,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。Java提供了...

    Forelax 评论0 收藏0

发表评论

0条评论

nidaye

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<