Java笔记——异常处理

    异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通 过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的错误条件。当条件生成时,错误将引发异常。


Java异常类层次结构图:



    Throwable类有两个重要的子类:Exception(异常)和 Error(错误),Error(错误)是程序中无法处理的错误,表示运行程序中较为严重的问题,程序本身无法处理。Exception(异常)则是程序本身可以处理的异常,下面主要说Exception(异常)的处理。

    在 Java 应用程序中,异常处理机制为:抛出异常或者捕捉异常。


一、捕获异常:try、catch 和 finally

     在Java中,异常通过try-catch语句捕获。其一般语法形式为:

try {  
    // 可能会发生异常的程序代码  
} catch (Type1 id1){  
    // 捕获并处置try抛出的异常类型Type1  
}  
catch (Type2 id2){  
     //捕获并处置try抛出的异常类型Type2  
}  
    关键词try后的一对大括号将一块可能发生异常的代码包起来,称为监控区域。Java方法在运行过程中出现异常,则创建异常对象。将异常抛出监控区域之 外,由Java运行时系统试图寻找匹配的catch子句以捕获异常。若有匹配的catch子句,则运行其异常处理代码,try-catch语句结束。


例1  捕捉throw语句抛出的“除数为0”异常。

public class TestException {  
    public static void main(String[] args) {  
        int a = 6;  
        int b = 0;  
        try { // try监控区域  
              
            if (b == 0) throw new ArithmeticException(); // 通过throw语句抛出异常  
            System.out.println("a/b的值是:" + a / b);  
        }  
        catch (ArithmeticException e) { // catch捕捉异常  
            System.out.println("程序出现异常,变量b不能为0。");  
        }  
        System.out.println("程序正常结束。");  
    }  
}  
运行结果:

程序出现异常,变量b不能为0。
程序正常结束。

    例1  在try监控区域通过if语句进行判断,当“除数为0”的错误条件成立时引发ArithmeticException异常,创建 ArithmeticException异常对象,并由throw语句将异常抛给Java运行时系统,由系统寻找匹配的异常处理器catch并运行相应异 常处理代码,打印输出“程序出现异常,变量b不能为0。”try-catch语句结束,继续程序流程。
    事实上,“除数为0”等ArithmeticException,是RuntimException的子类。而运行时异常将由运行时系统自动抛出,不需要使用throw语句。

例2  捕捉运行时系统自动抛出“除数为0”引发的ArithmeticException异常。

public static void main(String[] args) {  
    int a = 6;  
    int b = 0;  
    try {  
        System.out.println("a/b的值是:" + a / b);  
        } catch (ArithmeticException e) {  
            System.out.println("程序出现异常,变量b不能为0。");  
        }  
        System.out.println("程序正常结束。");  
}  
运行结果:

程序出现异常,变量b不能为0。
程序正常结束。


    try-catch语句还可以包括第三部分,就是finally子句。它表示无论是否出现异常,都应当执行的内容。try-catch-finally语句的一般语法形式为:

try {  
    // 可能会发生异常的程序代码  
} catch (Type1 id1) {  
    // 捕获并处理try抛出的异常类型Type1  
} catch (Type2 id2) {  
    // 捕获并处理try抛出的异常类型Type2  
} finally {  
    // 无论是否发生异常,都将执行的语句块  
}  

小结:

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。

当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:

1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。

二、抛出异常:throws

    如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。例如汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。
    throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。throws语句的语法格式为:

methodname throws Exception1,Exception2,..,ExceptionN  
{  
}  
    方法名后的throws Exception1,Exception2,...,ExceptionN 为声明要抛出的异常列表。当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理。例如:

import java.lang.Exception;  
public class TestException {  
    static void pop() throws NegativeArraySizeException {  
        // 定义方法并抛出NegativeArraySizeException异常  
        int[] arr = new int[-3]; // 创建数组  
    }  
  
    public static void main(String[] args) { // 主方法  
        try { // try语句处理异常信息  
            pop(); // 调用pop()方法  
        } catch (NegativeArraySizeException e) {  
            System.out.println("pop()方法抛出的异常");// 输出异常信息  
        }  
    }  
}  
    使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者。
    pop方法没有处理异常NegativeArraySizeException,而是由main函数来处理。

Throws抛出异常的规则:
1、 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
2、必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误。
3、仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣
4、调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。


例如:

void method1() throws IOException{}  //合法    
   
//编译错误,必须捕获或声明抛出IOException    
void method2(){    
  method1();    
}    
   
//合法,声明抛出IOException    
void method3()throws IOException {    
  method1();    
}    
   
//合法,声明抛出Exception,IOException是Exception的子类    
void method4()throws Exception {    
  method1();    
}    
   
//合法,捕获IOException    
void method5(){    
 try{    
    method1();    
 }catch(IOException e){…}    
}    
   
//编译错误,必须捕获或声明抛出Exception    
void method6(){    
  try{    
    method1();    
  }catch(IOException e){throw new Exception();}    
}    
   
//合法,声明抛出Exception    
void method7()throws Exception{    
 try{    
  method1();    
 }catch(IOException e){throw new Exception();}    
} 

三、Throwable类中的常用方法

注意:catch关键字后面括号中的Exception类型的参数e。Exception就是try代码块传递给catch代码块的变量类型,e就是变量名。catch代码块中语句"e.getMessage();"用于输出错误性质。通常异常处理常用3个函数来获取异常的有关信息:
     getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。
  getMeage():返回异常的消息信息。
  printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。


四、Java常见异常

在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:


1. runtimeException子类:
    1、 java.lang.ArrayIndexOutOfBoundsException
    数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
    2、java.lang.ArithmeticException
    算术条件异常。譬如:整数除零等。
    3、java.lang.NullPointerException
    空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
    4、java.lang.ClassNotFoundException
    找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
    5、java.lang.NegativeArraySizeException  数组长度为负异常
    6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
    7、java.lang.SecurityException 安全性异常
    8、java.lang.IllegalArgumentException 非法参数异常


2.IOException
IOException:操作输入流和输出流时可能出现的异常。
EOFException   文件已结束异常
FileNotFoundException   文件未找到异常


3. 其他
ClassCastException    类型转换异常类
ArrayStoreException  数组中包含不兼容的值抛出的异常
SQLException   操作数据库异常类
NoSuchFieldException   字段未找到异常
NoSuchMethodException   方法未找到抛出的异常
NumberFormatException    字符串转换为数字抛出的异常
StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
IllegalAccessException  不允许访问某类异常
InstantiationException  当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值