java异常与捕获

几乎所有的代码里面都会出现异常,为了保证程序在出现异常之后可以正常执行完毕,就需要进行异常处理

异常是导致程序中断执行的一种指令流。程序之中如果出现异常并且没有合理处理的话就会导致程序终止执行。

public class Test{
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
System.out.println("2.进行数学计算:"+10/0);
System.out.println("3.数学计算结束后");
}

}
1.数学计算开始前Exception in thread "main" 
java.lang.ArithmeticException: / by zero

at Test.main(Line.java:196)

现在程序之中产生了异常,但是异常语句之前的语句可以正常执行完毕,而异常产生之后程序直接结束,为了保证程序出现异常之后还可以继续向下执行,就需要异常处理。

异常处理格式:
try{
有可能出现异常的语句;
}[catch(异常类 对象)]{
}...]
[finally{
异常出口
}]

以上三个关键字可以出现的组合:try..catch 

                                                try..finally  

                                                try..catch..finally

范例:对异常进行处理


    public class Test{
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            System.out.println("2.进行数学计算:"+10/0);
        }catch(ArithmeticException e) {
            System.out.println("异常已经被处理了");
        }
        System.out.println("3.数学计算结束后");
    }

}
}


结果:

1.数学计算开始前
异常已经被处理了

3.数学计算结束后

以上代码虽然进行了异常处理,但是存在一个问题:你现在根本不知道程序产生了什么样的异样,所以为了明确的去的异样信息,可以直接输出异常类对象,或者调用所有异常类中提供的printStackTrace()方法进行完整异常信息的输出

public class Test{
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
try {
System.out.println("2.进行数学计算:"+10/0);
}catch(ArithmeticException e) {
e.printStackTrace();
}
System.out.println("3.数学计算结束后");
}

}

结果:1.数学计算开始前
java.lang.ArithmeticException: / by zero
at Line.main(Test.java:197)

3.数学计算结束后

public class Test{
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            System.out.println("2.进行数学计算:"+10/0);
        }catch(ArithmeticException e) {
            e.printStackTrace();
        }finally {
            System.out.println("[finally]不管是否产生异常,都执行此语句");
        }
        System.out.println("3.数学计算结束后");
    }

}

public class Test {
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            int x = Integer.parseInt(args[0]);
            int y = Integer.parseInt(args[1]);
            System.out.println("2.进行数学计算:" + x / y);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } finally {
            System.out.println("[finally]不管是否产生异常,都执行此语句");
        }
        System.out.println("[3].数学计算结束后");
    }
}

此时会出现如下问题:

用户没有输入初始化参数时:ArraylndexOutOfBoundsException

用户输入的不是数字:NumberFormatException

被除数为0:ArithmeticExceptio

以上发现,通过catch捕获异常的时候如果没有捕获指定异常,程序依然无法进行处理,现在最直白的解决方法就是使用多个catch块

public class Test{
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            int x=Integer.parseInt(args[0]);
            int y=Integer.parseInt(args[1]);
            System.out.println("2.进行数学计算:"+10/0);
        }catch(ArithmeticException e) {
            e.printStackTrace();
        }
        catch (NumberFormatException e) {
            e.printStackTrace();
        }
        catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }finally {
            System.out.println("[finally]不管是否产生异常,都执行此语句");
        }
        System.out.println("3.数学计算结束后");
    }

}

throws关键字
在进行方法定义的时候,如果要告诉调用者本方法可能产生哪些异常,就可以使用throws方法进行声明。即,如果该方法出现问题后不希望进行处理,就使用throw抛出。

throws用在方法上:

public class Test{
    public static void main(String[] args) {
 try{
            System.out.println(calculate(10,0));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static int calculate(int x,int y)throws Exception{
        return x/y;
    }

如果调用了throws声明的方法,那么在调用时必须明确的使用try...catch...进行捕获,因为该方法有可能产生异常,所以必须按照异常的方式来进行处理。

主方法本身也属于一个方法,所以在主方法上可以使用throws进行异常抛出,这个时候如果产生了异常就会交给JVM处理。

public class Test {
    public static void main(String[] args) throws Exception {


        System.out.println(calculate(10, 0));
    }


    public static int calculate(int x, int y) throws Exception {
        return x / y;


    }

}

throw关键字

直接编写在语句之中,表示人为进行异常的抛出。如果现在异常类对象实例化不希望由JVM产生而由用户产生,就可以使用throw来完成。

java.lang.Exception: 抛个异常玩玩

at Line.main(Line.java:233)

一般而言throw和break,continue,break都要和if结合使用。

面试题:

请解释throw和throws的区别:

1.throw用于方法内部,主要表示手工异常抛出。

2.throws主要在方法声明上使用,明确告诉用户本方法可能产生的异常,同时该方法可能不处理此异常。

RuntimeException类

public class Test{
    public static void main(String[] args) {


        String str="100";
        int num=Integer.parseInt(str);
        System.out.println(num*2);
    }

}

paseInt的源代码定义:public static int parseInt(String s) throws NumberFormatException

这个方法上已经明确抛出异常,但是在进行调用的时候发现,即使没有进行异常处理也可以正常执行。这个就属于RuntimeException的范畴。

很多的代码上都可能出现异常,例如"10/0"都可能产生异常,如果所有产生异常的地方都强制性异常处理,这个代码就太复杂了。所以在异常设计的时候,考虑到一些异常可能时是简单问题,所以将这类异常称为RuntimeException,也就是使用RuntimeException定义的异常类可以不需要强制性进行异常处理。

面试题:

请解释Exception与RuntimeException的区别,请列举几个常见的RuntimeException.

1.使用Exception是RuntimeException的父类,使用Exception定义的异常都要求必须使用异常处理,而使用RuntimeException定义的异常可以由用户选择性来进行异常处理。

2.常见的RuntimeException:ClassCastException,NullPointerException;

自定义异常类

自己定义一个异常类,自定义异常类可以继承两种父类:Exception 和RuntimeException.

class AddException extends Exception{
    public AddException(String msg) {
        super(msg);
    }
}
public class Test{
    public static void main(String[] args)throws Exception{
        int num1=20;
        int num2=30;
        if(num1+num2==50) {
            throw new AddException("错误的相加操作");
        }
    }
}

在项目的系统设计或者架构设计中,一定会涉及到相关业务的异常问题,此时需要自定义异常类。

猜你喜欢

转载自blog.csdn.net/xjy22/article/details/80088229