Java中异常的处理

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,否则编译不能通过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值