Java异常

异常

  异常是指程序在运行时产生的错误。比如在进行除法运算时,若除数为0,则运行时Java会自动抛出算术异常、若对一个值为null的引用变量进行操作,则会抛出空指针异常、若访问一个大小为2的一维数组中的第3个元素,则会抛出数组下标越界异常等。
  Java语言中的异常也是通过一个对象来表示的,程序运行时抛出的异常,实际上就是一个异常对象。该对象中不仅封装了错误信息,还提供了一些处理方法,如getMessage()方法获取异常信息、printStackTrace()方法输出对异常的详细描述信息等。

  对于可能出现的异常,都需要预先进行处理,保证程序的有效运行,否则程序会出错。在Java语言中已经提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,称为“受检查异常”;有的是由Java虚拟机自动进行捕获处理,称为“运行时异常”或“不受检异常”。  

  Java中常见的异常如下表所示:

异常类名称

异常类含义

ArithmeticException

算术异常类

ArrayIndexOutOfBoundsException

数组下标越界异常类

ArrayStoreException

将与数组类型不兼容的值赋值给数组元素时抛出的异常

ClassCastException

类型强制转换异常类

ClassNotFoundException

为找到相应类异常

EOFException

文件已结束异常类

FileNotFoundException

文件未找到异常类

IllegalAccessException

访问某类被拒绝时抛出的异常

InstantiationException

试图通过newInstance()方法创建一个抽象类或抽象接口的实例时抛出的异常

IOException

输入输出异常类

NegativeArraySizeException

建立元素个数为负数的数组异常类

NullPointerException

空指针异常类

NumberFormatException

字符串转换为数字异常类

NoSuchFieldException

字段未找到异常类

NoSuchMethodException

方法未找到异常类

SecurityException

小应用程序(Applet)执行浏览器的安全设置禁止的动作时抛出的异常

SQLException

操作数据库异常类

StringIndexOutOfBoundsException

字符串索引超出范围异常

  异常处理

  异常产生后,若不做任何处理,则程序就会被终止,为了保证程序有效的执行,就需要对产生的异常进行相应处理。在Java语言中,若某个方法抛出异常,既可以在当前方法中进行捕获,然后处理该异常,也可以将异常向上抛出,由方法的调用者来处理。

  下面来介绍Java中的异常处理方法。

 

  1.使用try…catch语句

    在Java语言中,对容易发生异常的代码,可通过try…catch语句捕获。在try语句块中编写可能发生异常的代码,然后在catch语句块中捕获执行这些代码时可能发生的异常。    

    try{
      可能产生异常的代码
     }catch(异常类 异常对象){
      异常处理代码
     }

 

 

    try语句块中的代码可能同时存在多种异常,那么到底捕获的是哪一种类型的异常,是由catch语句中的“异常类”参数来指定的。catch语句类似于方法的声明,包括一个异常类型和该类的一个对象,异常类必须是Throwable类的子类,用来指定了catch语句要捕获的异常,异常类对象可在catch语句块中被调用,例如调用对象的getMessage()方法获取对异常的描述信息。

  实例

    将一个字符串转换为整型,可通过Integer类的parseInt()方法来实现。当该方法的字符串参数包含非数字字符时,parseInt()方法会抛出异常。Integer类的parseInt()方法的声明如下:public static int parseInt(String s) throws NumberFormatException{…}。代码中通过throws语句抛出了NumberFormatException异常,所以在应用parseInt()方法时可通过try…catch语句来捕获该异常,从而进行相应的异常处理。

 

 

public class Test {

    /**
     * 将字符串“24L”转换为Integer类型,并捕获转换中产生的数字格式异常,可以使用如下代码:
     */
    public static void main(String[] args) {
        try {
            int age = Integer.parseInt("24L");
            System.out.println("打印1");
        } catch (Exception e) {
            System.out.println("年龄请输入整数!");
            System.out.println("错误:" + e.getMessage());
        }
        System.out.println("打印2");
    }
}

     因为程序执行到“Integer.parseInt("24L")”时抛出异常,直接被catch语句捕获,程序流程跳转到catch语句块内继续执行,所以“System.out.println("打印1")”代码行不会被执行;而异常处理结束后,会继续执行try…catch语句后面的代码。   

    说明:若不知代码抛出的是哪种异常,可指定它们的父类Exception。

  

    在try…catch语句中,可以同时存在多个catch语句块。一般格式为:

    try{

      可能产生异常的代码
    }catch(异常类1 异常对象){
      异常1处理代码
    }catch(异常类2 异常对象){
      异常2处理代码
    
}  

    代码中的每个catch语句块都用来捕获一种类型的异常。若try语句块中的代码发生异常,则会由上而下依次来查找能够捕获该异常的catch语句块,并执行该catch语句块中的代码。

    在使用多个catch语句捕获try语句块中的代码抛出的异常时,需要注意catch语句的顺序。若多个catch语句所要捕获的异常类之间具有继承关系,则用来捕获子类的catch语句要放在捕获父类的catch语句的前面。否则,异常抛出后,先由捕获父类异常的catch语句捕获,而捕获子类异常的catch语句将成为执行不到的代码,在编译时会出错。

     finally子句需要与try…catch语句一同使用,不管程序中有无异常发生,并且不管之前的try…catch是否顺利执行完毕,最终都会执行finally语句块中的代码,这使得一些不管在任何情况下都必须执行的步骤被执行,从而保证了程序的健壮性。

  2.使用throws关键字抛出异常

  若某个方法可能会发生异常,但不想在当前方法中来处理这个异常,那么可以将该异常抛出,然后在调用该方法的代码中捕获该异常并进行处理。将异常抛出,可通过throws关键字来实现。throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常,多个异常可用逗号分隔。

  实例 

 

public class Test {
    public static void main(String[] args) {
        try {
            doFile("D:/mytext.txt");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void doFile(String name) throws IOException {
        File file = new File(name);
        FileWriter fileOut = new FileWriter(file);
        fileOut.write("Hello,World!");
        fileOut.close();
        fileOut.write("爱护地球!");
    }
}

 

  结果

  对一个产生异常的方法,如果不使用try...catch语句捕获并处理异常,那么就必须使用throws关键字指出该方法可能会抛出的异常但如果异常类型是Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,Java虚拟机会捕获此类异常。将异常通过throws关键字抛给上一级后,如果仍不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的代码。

  3.使用throw关键字

  使用throw关键字也可抛出异常,与throws不同的是,throw用于方法体内,并且抛出一个异常类对象,而throws用在方法声明中来指明方法可能抛出的多个异常。通过throw抛出异常后,如果想由上一级代码来捕获并处理异常,则同样需要在抛异常的方法中使用throws关键字在方法的声明中指明要抛出的异常;如果想在当前的方法中捕获并处理throw抛出的异常,则必须使用try…catch语句。上述两种情况,若throw抛出的异常是Error、RuntimeException或它们的子类,则无须使用throws关键字或try…catch语句。

 

  实例  

public class Test {
    public static int check(String ageStr) throws Exception {
        int age = Integer.parseInt(ageStr);
        if (age < 0)
            throw new Exception("年龄不能为负数");
        return age;
    }

    public static void main(String[] args) {
        try {
            int myAge = check("-101");
            System.out.println(myAge);
        } catch (Exception e) {
            System.out.println("数据逻辑错误!");
            System.out.println("原因:" + e.getMessage());
        }
    }
}

  结果

  4.注意事项

    不能单独使用try、catch或finally语句块,否则编译出错;

    try语句块后既可以只使用catch语句块,也可以只使用finally语句块;

    当与catch语句块一起使用存在多个catch语句块,而对于finally语句块只能存在一个;

    当catch与finally同时存在时,finally必须放在catch之后;

    try语句块中声明的变量是局部变量,只在当前try语句快中起有效;

    对于发生的异常,必须使用try...catch语句捕获,或通过throws向上抛出,否则编译出错;

    当使用throw语句抛出一个异常对象时,该语句后面的代码不被执行。

  

  异常类

  1.Throwable类

    在Java语言中提供了一些内置的异常类来描述经常较容易发生的错误,这些类都继承自java.lang.Throwable类。Throwable类有两个子类:Error和Exception,它们分别表示两种异常类型。内置异常类的结构如图所示:

   2.Error类

    Error类及其子类通常用来描述Java运行系统中的内部错误以及资源耗尽的错误。Error表示的异常是比较严重,仅靠修改程序本身是不能恢复执行的,被称为致命异常类。在大多数情况下,发生该异常时,建议终止程序。

  3.Exception类

    Exception类可称为非致命异常类,它代表了另一种异常。发生该异常的程序,通过捕获处理后可正常运行,保持程序的可读性及可靠性。在开发Java程序过程中进行的异常处理,主要就是针对该类及其子类的异常处理。对程序中可能发生的该类异常,应该尽可能进行处理,以保证程序在运行时,能够顺利执行,而不应该在异常发生后终止程序。

    Exception类又分为两种异常类型:
    RuntimeException异常
    检查异常及其他异常。

    >RuntimeException是运行时异常,也称为不检查异常(unchecked exception),是程序员编写的程序中的错误导致的,修改了该错误后,程序就可继续执行。当RuntimeExeption类或其子类所描述的异常发生后,可以不通过try…catch、throws捕获或抛出,在编译时是可以通过的,只是在运行时由Java虚拟机来抛出。常见异常:

 

异常类名称

异常类含义

ArithmeticException

算术异常类

ArrayIndexOutOfBoundsException

数组下标越界异常类

ArrayStoreException

将与数组类型不兼容的值赋值给数组元素时抛出的异常

ClassCastException

类型强制转换异常类

IndexOutOfBoundsException

当某对象(如数组或字符串)的索引超出范围时抛出该异常

NegativeArraySizeException

建立元素个数为负数的数组异常类

NullPointerException

空指针异常类

NumberFormatException

字符串转换为数字异常类

SecurityException

小应用程序(Applet)执行浏览器的安全设置禁止的动作时抛出的异常

StringIndexOutOfBoundsException

字符串索引超出范围异常

 

     >检查异常:如果一个记者根据上级指定的地址去采访一个重要人物,这可能会抛出异常,例如根据指定地址没有找到被采访的人或采访被拒绝。该类异常被称为检查异常(check exception),要求必须通过try…catch捕获或由throws抛出,否则编译出错。Java语言中常见的检查异常如下表所示:

异常类名称

异常类含义

ClassNotFoundException

未找到相应类异常

EOFException

文件已结束异常类

FileNotFoundException

文件未找到异常类

IllegalAccessException

访问某类被拒绝时抛出的异常

InstantiationException

试图通过newInstance()方法创建一个抽象类或抽象接口的实例时抛出该异常

IOException

输入输出异常类

NoSuchFieldException

字段未找到异常

NoSuchMethodException

方法未找到异常

SQLException

操作数据库异常类

     >通常使用Java内置的异常类就可以描述在编写程序时出现的大部分异常情况,但根据需要,有时要创建自己的异常类,并将它们用于程序中来描述Java内置异常类所不能描述的一些特殊情况。下面就来介绍如何创建和使用自定义异常。自定义的异常类必须继承自Throwable类,才能被视为异常类,通常是继承Throwable的子类Exception或Exception类的子孙类。除此之外,与创建一个普通类的语法相同。

    使用步骤:

      (1)创建自定义异常类

      (2)在方法中通过throw抛出异常对象

      (3)若在当前抛出异常的方法中处理异常,可使用try…catch语句捕获并处理;否则在方法的声明处通过throws指明要抛出给方法调用者的异常,继续进行下一步操作。

      (4)在出现异常的方法调用代码中捕获并处理异常。

    如果自定义的异常类继承自RuntimeExeption异常类,在步骤(3)中,可以不通过throws指明要抛出的异常。

 

   实例

//自定义MyException类
public
class MyException extends Exception { private String content; public MyException(String content) { this.content = content; } public String getContent() { return content; } }
//测试类
public
class Test { public static void check(String str) throws MyException { char a[] = str.toCharArray(); int i = a.length; for (int k = 0; k < i - 1; k++) { if (!((a[k] >= 65 && a[k] <= 90) || (a[k] >= 97 && a[k] <= 122))) throw new MyException("字符串\"" + str + "\"中含有非法字符"); } } public static void main(String[] args) { String str1 = "HelloWorld"; String str2 = "Hello!World!"; try { check(str1); check(str2); } catch (MyException e) { System.out.println(e.getContent()); e.printStackTrace(); } } }

   结果

 

 

 

非原创,当复习笔记用!来自《Java实用教程》--肖磊、李钟尉

posted @ 2018-01-14 01:00  maxudong  阅读(179)  评论(0)    收藏  举报