Java 异常

来源:互联网 发布:空知英秋 知乎 编辑:程序博客网 时间:2024/05/11 13:44

Java异常是指发生在程序执行过程中错误事件,Java预先定义了很多异常类,如下:

这里写图片描述

Throwable 类是 Java 语言中所有错误或异常的超类,它又可以分为两种类型(两个子类):
1)Error:表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,(除特殊情况,一般自己不用关心)比如OutOfMemoryError
2)Exception:表示程序本身可以处理的异常,它又分为两大类:
 • 运行时异常 RuntimeException(又称不受检查异常 Unchecked Exception):编译器不会检查程序是否对运行时异常作了处理,不必捕获或者抛出运行时异常,当其发生时,表示程序出现了编程错误,常见的运行时异常:NullPointerExceptionIndexOutOfBoundsExceptionClassCastException
 • 受检查异常 Checked Exception:所有继承Exception但不是RuntimeException的异常都是受检查异常,如上图中的IOExceptionClassNotFoundException。Java语言规定必须对受检查异常进行处理,编译器会对此检查,要么在方法声明中抛出,要么使用try … catch语句捕获

异常的处理
异常有两种处理方法一是直接抛出,而是使用try-catch捕获
(1)抛出异常,关键字throw、throws
抛出异常又可以分为两种方法,一是在方法声明时使用 throws 关键字抛出;二是在方法中使用 throw 关键字抛出。
 • throw:有时我们需要显式地创建并抛出异常对象来终止程序的正常执行。throw关键字用来抛出并处理运行时异常
 • throws:当我们抛出任何“被检查的异常(checked exception)”并不处理时,需要在方法签名中使用关键字throws来告知调用程序此方法可能会抛出的异常。调用方法可能会处理这些异常,或者同样用throws来将异常传给上一级调用方法。throws关键字后可接多个潜在异常,甚至是在main()中也可以使用throws

public class ExceptionTest {    public static void main(String[] args) throws  FileNotFoundException, IOException, ClassNotFoundException {        Fruit apple = new Fruit("Apple");        serializeObject(apple);        ObjectInputStream in = new ObjectInputStream(new FileInputStream("Fruit.out"));        Fruit res = (Fruit) in.readObject();        in.close();        System.out.println(res.name);    }    static void serializeObject(Object obj) throws FileNotFoundException, IOException{        if(obj == null){            // 在方法中抛出具体的异常            throw new NullPointerException("要序列化的对象不能为空");        }        // 当要将对象序列化到文件时,需要处理异常,这里用 throws 直接在方法声明时抛出        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Fruit.out"));        out.writeObject(obj);        out.close();    }    static class Fruit implements Serializable{        String name;        public Fruit(){}        public Fruit(String name){            this.name = name;        }    }}

(2)捕获异常,关键字try、catch、finally
  我们在代码中使用 try-catch 块处理异常,一个try块之后可以有多个catch子句,try-catch块也能嵌套。每个catch块必须接受一个(且仅有一个)代表异常类型的参数,当try块出现异常,就会进入catch块进行匹配,只有匹配的catch才会被执行
  finally块是可选的,并且只能配合try-catch一起使用,不管异常有没有出现,finally块总会被执行,一般用来释放资源
  在以下几种情况会进入finally块:
  • try块中的代码正常执行完毕
  • 在try块中抛出异常
  • 在try块中执行return、break、continue

public class ExceptionTest {    public static void main(String[] args) {        Fruit apple = new Fruit("Apple");        serializeObject(apple);        Fruit res = null;        ObjectInputStream in = null;        // 由于Exception是所有受检查异常的基类,因此可用一个catch块来捕获所有可捕获异常        try {            in = new ObjectInputStream(new FileInputStream("Fruit.out"));            res = (Fruit) in.readObject();        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                in.close();            } catch (IOException e) {                e.printStackTrace();            }        }        System.out.println(res.name);    }    static void serializeObject(Object obj){        if(obj == null){            // 在方法中抛出具体的异常            throw new NullPointerException("要序列化的对象不能为空");        }        ObjectOutputStream out = null;        // 使用try-catch捕获异常        // 在这里有多个catch块,FileNotFoundException是IOException的子类,只能放在它的前面        try {            out = new ObjectOutputStream(new FileOutputStream("Fruit.out"));            out.writeObject(obj);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally { // 在finally块中关闭输出流            try {                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    static class Fruit implements Serializable{        String name;        public Fruit(){}        public Fruit(String name){            this.name = name;        }    }}

Java 自定义异常
  当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。需要注意的是,唯一有用的就是类型名这个信息,所以不要在异常类的设计上花费精力

public class ExceptionTest {    static class MyException extends Exception{        public MyException() {}        public MyException(String msg) { super(msg); }    }    static void f() throws MyException{        System.out.println("Throwing MyException from f()");        throw new MyException();    }    static void g() throws MyException{        System.out.println("Throwing MyException from g()");        throw new MyException("Originated in g()");    }    public static void main(String[] args) {        try{            f();        } catch(MyException e){            // 调用默认的printStackTrace()则输出到标准错误流System.err            e.printStackTrace(System.out);        }        try{            g();        } catch(MyException e){            e.printStackTrace(System.out);        }    }}输出结果:Throwing MyException from f()com.test.ExceptionTest$MyException    at com.test.ExceptionTest.f(ExceptionTest.java:19)    at com.test.ExceptionTest.main(ExceptionTest.java:28)Throwing MyException from g()com.test.ExceptionTest$MyException: Originated in g()    at com.test.ExceptionTest.g(ExceptionTest.java:23)    at com.test.ExceptionTest.main(ExceptionTest.java:34)

Java 异常类常用的方法
  异常类没有提供特殊方法供使用,它们的所有方法都是来自其基类Throwable
  • getMessage():返回此 throwable 的详细消息字符串
  • printStackTrace():该方法打印异常堆栈信息。该方法能接受PrintStream 和PrintWriter作为参数实现重载,这样就能实现打印栈轨迹到文件或流中
  • getCause():返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null
  • toString():返回此 throwable 的简短描述。结果是以下字符串的串联:此对象的类的 name ,”: “(冒号和一个空格),调用此对象 getLocalizedMessage() 方法的结果

http://blog.csdn.net/u012567997/article/details/17114595
http://blog.csdn.net/u013014054/article/details/17173785
http://www.importnew.com/7383.html

0 0