赞
踩
什么是异常?
异常就是那些你知道他可能发生的,或者你不知道的预期之外的状况。比如数组越界,网络连接失败,打开一个不存在的文件,要求输入正数你却输入负数,非法参数等等。
为什么要关注这个异常?
我们希望程序发生错误时能够保持理智行为,即有对应的措施。而不时遇到错误终止程序。我们希望程序出现错误时可以返回到一种安全的状态,并执行其他操作,或者保存所有操作的结果,以妥善的方式终止程序。
下面举个简单的例子
public static void main(String[] args) {
int num1 = 1;
int num2 = 0;
System.out.println(num1);
System.out.println(num1 / num2); //分母为0,异常
System.out.println(num2);
}
我们知道除法的分母是不可以为0的,来看一下他的结果,他会输出所有语句吗?
1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at CSDN.main(CSDN.java:10)
我们看到第一行输出了 num1 的值1,没有输出 1/0 的结果,没有输出num2的值。这是因为程序按顺序进行,到第二条输出语句时有一个算数异常(ArithmeticException),然后就终止了程序。
异常的分类
Java中异常对象都说派生于Throwable类的一个实例。
这是Java异常层次的简化图
所有的异常都是从Throwable继承而来,但是下一层就分成了 Error 和 Exception两类,然后又派生更多的类。
Error类描述的是系统内部错误和资源耗尽错误。发生这类错误除了通告给用户,并尽力使程序终止外,再也无能为力。
要关注Exception类的层次结构,包括两个分支RuntimeException 和其他异常。
RuntimeException异常:程序错误所导致的异常叫RE异常(RE是缩写),也叫非受查异常。
其他异常:程序本身没有问题,由于想I/O错误导致的叫其他异常,也叫受查异常。
受查异常(checked)
比如:
IOException(同输入输出相关的操作,如无效输入,打开一个不存在在文件)
ClassNotFoundException(使用不存在的类)
特征:编译就不能通过。方法要抛出的受查异常必须在方法头中显示声明,然后编译器会核查是否为所有的受查异常提供了构造器(try-catch)。
非受查异常(unchecked)
比如:
ArithmeticException(算数异常)
NullPointerException(指向对象为空异常)
IndexOutOfBoundsException(数组超标异常)
IllegalArgumentException(传递非法参数异常)
特征:可以通过编译,从名字知道,他的错误发生在运行时,上面的 1/0 就是一个算数异常,它可以通过编译,但无法运行。不要求显示声明非受查异常(try-catch是无法解决RE异常的,但是仍旧可以捕捉RE异常)。
再看几个例子对比一下
(以下是受检异常)
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num1 = in.nextInt();
int num2 = in.nextInt();
System.out.println(num1);
System.out.println(num2);
in.close();
}
输出结果
4 3.5
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at CSDN.main(CSDN.java:9)
抛出异常,没有构造器
public static void main(String[] args) throws IOException{
Scanner in = new Scanner(System.in);
int num1 = in.nextInt();
int num2 = in.nextInt();
System.out.println(num1);
System.out.println(num2);
in.close();
}
输出结果(一样)
4 3.5
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at CSDN.main(CSDN.java:10)
抛出异常,添加构造器
(程序为了简单把输入两个数变成一个)
public static void main(String[] args) throws IOException { Scanner in = new Scanner(System.in); boolean continueInput = true; do { try { int num1 = in.nextInt(); System.out.println("The num1 is " + num1); continueInput = false; } catch (InputMismatchException e) { /** 第一次输类型的时候没多想就输入了IOException,InputMismatchException是 IOException的子类,派生类,子类能不获得父类不一定能捕获,反之亦然,但是方法头 可以声明某个派生类(catch的异常类)的父类的异常类型,比如抛出Throwable也是可以 的但是不建议这么做,抛出的异常多了你就不知道哪个是哪个了 */ System.out.println("Try again.(Incorret input: an integer is required )"); in.nextLine(); } } while (continueInput); in.close(); }
输出结果
3.4
Try again.(Incorret input: an integer is required )
3
The num1 is 3
不抛出异常,有构造器
public static void main(String[] args) { Scanner in = new Scanner(System.in); boolean continueInput = true; do { try { int num1 = in.nextInt(); System.out.println("The num1 is " + num1); continueInput = false; } catch (InputMismatchException e) { System.out.println("Try again.(Incorret input: an integer is required )"); in.nextLine(); } } while (continueInput); in.close(); }
输出结果是一样的,因为异常已经被捕获了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。