程序中总有些意想不到的状况所引发的错误,Java中的错误也以对象方式呈现为java.lang.Throwable的各种子类实例。只要你能捕捉包装错误的对象,就可以针对该错误做一些处理,例如,试恢复正常流程、进行日志( Logging)记录、以某种形式提醒用户等
1、使用try、catch
如下小程序,用户可以连续输入整数最后输入0结束后会显示输入数的平均值
package errorDemo;
import java.util.*;
public class Average {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
double sum = 0;
int i = 0;
while(true) {
int num=scan.nextInt();
if(num==0) {
break;
}
sum+=num;
i++;
}
System.out.printf("%.1f%n",sum/i);
}
}
如果用户不小心输入错误,例如第二个数输入为o,而不是0:
7
o
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Unknown Source)
at java.base/java.util.Scanner.next(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
at errorDemo.Average.main(Average.java:10)
这段错误信息对除错是很有价值的,错误信息的第一行:Exception in thread "main" java.util.InputMismatchException
Scanner对象的nextInt()方法,可以将用户输入的下一个字符串剖析为int值,出现InputMismatchException错误信息表示不符合 Scanner对象预期,因为下一个字符串本身要代表数字。
Java中所有错误都会被打包为对象后做一些处理。可以尝试(try)捕捉(catch)代表错误的对象后做一些处理 例如:
package errorDemo;
import java.util.*;
public class Average {
public static void main(String[] args) {
try{
Scanner scan=new Scanner(System.in);
double sum = 0;
int i = 0;
while(true) {
int num=scan.nextInt();
if(num==0) {
break;
}
sum+=num;
i++;
}
System.out.printf("%.1f%n",sum/i);
}catch(InputMismatchException ex) {
System.out.println("输入整数");
}
}
}
这里使用了try、 catch语法,JVM会尝试执行try区块中的程序代码。如果发生错误,执行流程会跳离错误发生点,然后比较 catch括号中声明的类型,是否符合被抛出的错误对象类型,如果是的话,就执行 catch区块中的程序代码。
执行完毕后进行try,catch之后的代码。
尝试恢复正常流程:
package errorDemo;
import java.util.*;
public class Average {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double sum = 0;
int i = 0;
while (true) {
try {
int num = scan.nextInt();
if (num == 0) {
break;
}
sum += num;
i++;
} catch (InputMismatchException ex) {
System.out.printf("忽略非整数%s%n",scan.next());
}
}
System.out.printf("%.1f%n", sum / i);
}
}
如果nextInt()方式错误InputMismatchException,程序跳到catch,执行catch区域后,还在while循环,可以继续下一个循环流程。(但是并不建议捕捉InputMismatchException)
2、异常继承架构
在先前的 Average范例中,虽然没有撰写try、ctch语句,照样可以编译执行。但是这样撰写,编译却会错误:
int a =System.in.read();
要解决这个错误信息有两种方式,一是使用try、 catch打包System.in.read();在main()方法旁声明throws java.io.IOException。简单来说,编译程序认为System. in read()时有可能发生错误,要求你一定要在程序中明处理错误。
例如,若这样撰写就可以通过编译:
try {
int a=System.in.read();
}catch(java.io.IOException ex) {
ex.printStackTrace();
}
Average范例与这里的例子,程序都有可能发生错误,编译程序单单就只要求这里的范例一定要处理错误。要了解这个问题,得先了解那些错误对象的继承架构:
首先要了解错误会被包装为对象,这些对象都是可抛出的(稍后介绍 throw语法,就会了解如何抛出错误对象),因此设计错误对象都承自java.lang.Throwable类, Throwable定义了取得错误信息、堆栈追踪( (Stack Trace)等方法,它有两个子类Java. lang.Exception和Java. lang. Error。
Error与其子类实例代表严重系统错误,如硬件层面错误、JVM错误或内存不足等问题。虽然也可以使用try、 catch来处理 Error对象,但并不建议,发生严重系统错误时Java应用程序本身是无力回复的。举例来说,若JVM所需内存不足,不可能撰写程序要求操作系统给予JVM更多内存。Error对象抛出时,基本上不用处理,任其传播至JVM为止,或者是最多留下日志信息。
(如果抛出了 T