Java中异常的处理

来源:互联网 发布:淘宝网店名字女童店 编辑:程序博客网 时间:2024/05/24 05:43

Java中的异常

分为Error和Exception,其中Error是指Java虚拟机无法解决的严重问题,Exception是指外在因素导致的一般性问题,这里我们讨论的是Exception。

常见的Exception

有空指针异常、数组下标越界异常、类型转换异常、算术异常。

Exception的处理

抓抛模型:抓是指抓住上一步抛出的异常;抛是指代码执行出现异常,将会在异常处生成一个对应的异常类对象,并将此对象跑出给方法的调用者。三种方式来处理,第一种时try-catch-finally(finally为可选),第二种是在方法定义的后面追加throws xxException,其中try-catch-finally是在此处真正处理掉异常的,以后如果再有方法调用这个异常代码块直接调用即可,不用做处理;而throws xxException形式的处理方式,只是单纯的抛出异常,并未做实际处理,所以没有只要有方法调用这个异常代码块还是要做异常处理,因为这个异常代码处理异常的方式是将异常抛给方法的调用者了。第三种是自定义异常类,用关键字throw手动抛出,如下两个代码段:

        Scanner is = new Scanner(System.in);        try {            int s = is.nextInt();            System.out.println(s);        } catch (InputMismatchException e) {            System.out.println("类型转换出错了!");        } finally {        System.out.print("我是finally");        }

再看

public class TestExceptionWithThrows {    //这里mian()方法接收到method2抛出的异常,需要对他进行处理,如果这里在采用throws的继续往上抛出的话    //那么异常将会抛给JVM来处理,但是可以看出throws这样的声明式的抛出异常的方式并不是处理异常最根本的方法,最根本的方法应该    //是try-catch这样的方式,而且如何在异常代码块已经执行了try-catch方式处理过后,那么调用它的方法将不用再最它的异常进行处理    //不想throws方式不断往上抛出,上一级还要不断的对下一级的异常进行处理    public static void main(String[] args){        try {            method2();        } catch (FileNotFoundException e) {            System.out.println(e.getMessage());        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    //这里method()方法将异常抛给了method2(),然后这里method2()也是采用throws的方式将异常往上一级抛出    public static void method2 () throws FileNotFoundException,IOException {        method();    }    //这里将异常抛给调用者    public static  void method() throws FileNotFoundException,IOException {        FileInputStream fis = new FileInputStream(new File("hellow.text"));        int b;        while((b = fis.read())!=-1){            System.out.println((char)b);        }        fis.close();    }}

其中finally中的代码无论是否发生异常,都肯定会执行的,而且注意他们的执行顺序是先执行try{}中的代码块,如何发生异常,那么直接跳到finlly{}的代码块,先执行finally中的代码块,然后再返回来处理异常,执行catch{}中的代码块,如果没有finally{}代码块,则先处理异常再执行后续代码,并且如果有多个异常,那么catch的时候,就会从上到下的寻找对应的异常处理方式,处理完退出catch块,并且这里注意多个catch()中的异常顺序从上到下必须是范围小的异常到范围大的异常。如

catch(FileNotFoundException e){}catch(Exception e){}

这里看一下综合代码

public class ReturnExceptionDemo {    static void methodA() {        try{            System.out.println("进入方法A");            //手动抛出一个异常            throw new RuntimeException("制造异常");        } finally {            System.out.println("调用A方法的finally");        }    }    static void methodB() {        try{            System.out.println("进入方法B");            return;        } finally {            System.out.println("调用B方法的finally");        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        try {            methodA();        } catch (Exception e) {            System.out.println(e.getMessage());        }        methodB();    }}

它的运行结果为:
进入方法A
调用A方法的finally
制造异常
进入方法B
调用B方法的finally

这里需要注意的还有就是当try{}代码块中有return时,finally{}块中的代码还是会执行,执行后才会执行return,执行完return之后该方法将会被销毁。

这里除了手动抛出已存在的异常,我们还可以自定义异常,自定的异常一定要继承已有的异常类,如Exception或者RuntimeException,然后重写父类的构造方法,一般只要重写一下(String msg, Throwable)和(String msg)就可以了,其他都不需要动,如下:

//自定义的异常类,必须继承现有的异常类,提供几个重载的构造器即可public class MyException extends RuntimeException {    private static final long serialVersionUID = 1L;    public MyException(String message, Throwable cause) {        super(message, cause);        // TODO Auto-generated constructor stub    }    public MyException(String message) {        super(message);        // TODO Auto-generated constructor stub    }}

调用异常

/** * 手动抛出异常,自定义异常的信息 * @author Weiguo Liu * */public class TestExceptionWithHand {    public static void main(String[] args) {        Circle c1 = new Circle(2.1);        Circle c2 = new Circle(2.1);        System.out.println(c1.compareTo(c2));        System.out.println(c1.compareTo(new String ("asda")));    }}   class Circle {    private double radius;//圆的半径    public double getRadius() {        return radius;    }    public void setRadius(double radius) {        this.radius = radius;    }    public Circle(double radius) {        super();        this.radius = radius;    }    public int compareTo(Object obj) {        if(this == obj) {            return 0;        }else if(obj instanceof Circle){            Circle c = (Circle)obj;            if(this.radius>c.radius){                return 1;            }else if(this.radius == c.radius){                return 0;            }else{                return -1;            }        }else{            //手动的抛出异常            throw new MyException("传入的类型有误!");        }    }}

这里有一点需要注意的是,如果手动抛出异常的话,即throw new xxException,那么必须对这个异常进行try-catch或者在方法后面throws xxException,否则编译不能通过。

原创粉丝点击