java异常处理
出现异常
public class Throwa {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("除法计算"+(10/0));//此处错误后,此行和之后的代码不再运行
System.out.println("除法计算结束");
}
}
错误提示:
Thread [main] (Suspended (exception ArithmeticException))
Throwa.main(String[]) line: 6
程序出现异常,导致程序的中断。中断也想程序继续运行。
public class Throwa {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println("除法计算"+(10/0));//异常出现之后的代码都不执行
System.out.println("************");
}catch(ArithmeticException e){
System.out.println("出现异常"+e);
}
System.out.println("除法计算结束");
}
}
//出现异常java.lang.ArithmeticException: / by zero
除法计算结束
此时程序出现异常之后,发现将直接跳转到catch之中进行处理,处理完成之后,程序正常结束。
public class Throwa {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println("除法计算"+(10/0));//异常出现之后的代码都不执行
System.out.println("************");
}catch(ArithmeticException e){
System.out.println("出现异常"+e);
}finally{
System.out.println("##不管是否有异常都有执行");
}
System.out.println("除法计算结束");
}
}
但是在进行异常信息输出的时候,如果直接输出异常对象,那么只是告诉用户是什么异常,但是异常信息并不完整,那么如果希望异常的信息完整
可以调用异常类之中的“printStackTrace()‘方法进行完整输出
public class Throwa {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println("除法计算"+(10/0));
System.out.println("************");
}catch(ArithmeticException e){
e.printStackTrace();//完整信息
//System.out.println("出现异常"+e);
}
System.out.println("除法计算结束");
}
}
范例:现在希望通过初始化参数,来输出两个计算的数字
public class Throwb {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//接收参数数据,并且将其转为int型数据
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
System.out.println("除法计算:"+(x/y));
System.out.println("************");
}catch(ArithmeticException e){
e.printStackTrace();//完整信息
//System.out.println("出现异常"+e);
}
System.out.println("除法计算结束");
}
}
这时代码可能下面的问题:
问题一;执行的时候没有输入参数(java Thread ):(ArrayIndexOutOfBoundsException)),未处理
问题二:输入的不是数字(java Thread a b):NumberFormatException,未处理。
问题上:输入数据的被除数是0,(java Thread 10,0):ArithmeticException,已处理
那么现在发现程序之中,如果某些异常没有进行处理,那么程序依然会中断执行。
范例:使用多catch操作
public class Throwb {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//接收参数数据,并且将其转为int型数据
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
System.out.println("除法计算:"+(x/y));
System.out.println("************");
}catch(ArithmeticException e){
e.printStackTrace();//完整信息
//System.out.println("出现异常"+e);
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}catch(NumberFormatException e) {
e.printStackTrace();
}finally {
System.out.println("##不管是否有异常都有执行");
}
System.out.println("除法计算结束");
}
}
此时已经可以成功的进行所有异常的处理,但是所有的异常都是经过大量的分析之后才可以得出的处理,那么既然分析完了,那么有if else判断要比
使用try...catch更加简单,那么异常处理有什么用??
异常的处理流程
java之中之所以提供异常处理机制,主要目的就是希望可以减少用户的if..else判断。
要想解决异常问题,首先来看一下关于异常的继承结构
ArithmeticException | NumberFormatException |
java.lang.Object 继承者 java.lang.Throwable 继承者 java.lang.Exception 继承者 java.lang.RuntimeException 继承者 java.lang.ArithmeticException | java.lang.Object 继承者 java.lang.Throwable 继承者 java.lang.Exception 继承者 java.lang.RuntimeException 继承者 java.lang.IllegalArgumentException 继承者 java.lang.NumberFormatException |
发现所有的异常都继承了Throwable类,而这个类指就是抛出信息的操作类。在这个类有有个子类。
面试题:它们两个的区别
Error: 表示的是JVM系统出错,此时程序还没有执行,所以用户不能处理
Exception:表示的是所有程序运行过程之中出现的异常,用户可以进行处理
一般而言,由于Throwable表示的范围太大了,那么程序程序之中处理往往不会是Throwable,而都是Exception
按照之前对象的向上转型自动完成的概念上来讲,所有的子类对象都可以使用父类接收,那么就表示所产生出来的所有异常都是Exception的子类,
所有的异常对象都应该可以自动转为Exception。
面试题:请解释异常流程:
1.当程序在运行过程之中产生了异常之后,那么自动由JVM根据产生的异常类型,自动实例化一个与之相匹配的异常类对象(对象可以进行引用转递,可以包含很多的信息)
2.此时程序JVM会判断在出现异常的代码之中是否存在有try语句进行异常的捕获。
3.如果现在存在有try语句,则会由try捕获异常异常类的实例化对象,如果没有try,那么表示没有异常处理,这会交给JVM默认处理。
4.如果此时存在有try,那么会由try捕获异常,而后与try语句之后的每一个catch进行匹配。如果当前catch不匹配,则会交给catch继续匹配;
5.如果有匹配成功的catch则适应语句之中的代码进行异常处理,如果始终没有匹配的catch,那么会将异常交给JVM执行默认处理
6.如果现在在程序之中在有finally代码,那么在所有catch无法进行异常处理的时候,会判断是否有finally代码,如果有finally,则执行finally之中的程序后交给JVM默认处理,
所有的catch执行完毕之后也要判断是否存在有finally代码。
7.进入到finally代码之中有两种情况,一种是没有处理,则执行完finally代码之后,这之后的程序将不再执行,而如果已经处理完异常,则继续执行finally之后的程序
通过以上的分析可以发现,所谓的异常处理与catch匹配异常,那么就非常类似于方法的参数转递过程,唯一不同的是,此时的方法名称都统一
使用了catch关键字表示,而所有的调用过程由try自动完成,那么既然是一个参数转递过程,就可以按之前所学过的对象自动向上转型的方法进行处理,所有的异常都是Exception的子类,那么
所有的异常都可以使用Exception处理。
public class Throwb {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//接收参数数据,并且将其转为int型数据
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
System.out.println("除法计算:"+(x/y));
System.out.println("************");
}catch(Exception e){
e.printStackTrace();//完整信息
//System.out.println("出现异常"+e);
}finally {
System.out.println("##不管是否有异常都有执行");
}
System.out.println("除法计算结束");
}
}
提示:在使用多个catch进行处理的时候,捕获范围小的异常一定要放在捕获范围大的异常之前,不然会出现编译错误
如果要求不严格的情况下,那么就可以使用Exception处理所有的异常信息,这也是大部分系统常用的做法。