Java异常处理
Java中的异常不同于语法错误,语法错误在类文件编译时就会直接失败,而异常是只在程序运行过程中出现的一此预想之外的问题。有些错误问题并不会影响程序的运行,然而对大多数的异常而言,如果它们发生时开发者不做处理,程序会被直接终止并在控制台输出异常信息。
Java中的异常机制是基于面向对象的一种运行错误处理机制。Java把大部分可能存在的异常信息都封装成各自对应的类,所有这些异常类都继承自Throwable类,而Java中出现的异常都是对象。Throwable类有两个子类,分别是Error类和Exception类。Error类及其子类会在Java程序运行中发生内部错误或导致内存资源不足时而被抛出,此时程序会被直接终止;Exception类及其子类是通过异常捕获的方式对开发人员或程序中的错误进行提示,程序会继续执行,不会被终止。Error类被抛出时,一般是程序内部出现了较为严重的错误;Exception类被抛出时,一般分为运行时异常和非运行时异常。
异常处理的两种方式
package demo; import java.util.InputMismatchException; import java.util.Scanner; //多个catch语句 public class Test { public static void main(String[] args) { int a=10; int b=0; int[]arr={1,2,3}; try{ System.out.println(a/b); System.out.println(arr[5]); }catch(ArithmeticException ae){ System.out.println("获得异常"); ae.printStackTrace(); System.out.println("over"); }catch (ArrayIndexOutOfBoundsException aio){ System.out.println("越界"); }catch (InputMismatchException in){ System.out.println("输入异常"); in.printStackTrace();//打印具体异常信息 } System.out.println("下面的代码"); System.out.println("下面的代码"); System.out.println("下面的代码"); } } 运行结果; 获得异常 over 下面的代码 下面的代码 下面的代码 java.lang.ArithmeticException: / by zero at demo.Test.main(Test.java:17)
注意事项:
finally
被finally控制的语句体一定会执行(前提jvm没有停止)
特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))
finally的作用:用来进行善后工作,例如释放资源,在IO流操作和数据库操作中会见到
package demo; import java.util.*; //finally处理善后工作 public class Test6 { public static void main(String[] args) { Scanner sc=null; try { sc=new Scanner(System.in); System.out.println("请输入一个整数:"); int num = sc.nextInt(); System.out.println(num); }catch (InputMismatchException a){ System.out.println("输入异常"); }finally { if (sc != null) { sc.close(); System.out.println("这里的语句都会执行"); } } } } 运行结果: 请输入一个整数: aa 输入异常 这里的语句都会执行
Java中的异常被分为两大类:编译时异常和运行时异常。
所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常:
编译时异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常:无需显示处理,也可以和编译时异常一样处理
throws
throws的方式处理异常
定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
那么就通过throws在方法上标识。
Throwable
public String getMessage():获取异常信息,返回字符串
public String toString() :获取异常类名和异常信息,返回字符串
public vod printStackTrace():打印具体的异常信息
printStackTrace(PrintStream s) :将此 throwable 及其追踪输出到指定的输出流。
throw
throw的概述:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
throws和throw的区别
throws
用在方法声明后面,跟的是异常类名 可以跟多个异常类名,用逗号隔开 表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
这个异常对象可以是编译期异常对象,可以是运行期异常对象
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
自定义异常
我们在开发过程中,可能会遇到各种问题,而JDK不可能针对每一种问题都给出具体的异常类与之对应。为了满足需求,我们就需要自定义异常。
例如:考试成绩必须在0-100之间,不满足就产生异常。
自定义异常概述 需要将我们自定义的异常类纳入到我们的异常体系中
继承自Exception
继承自RuntimeException
package demo2; import java.util.Scanner; //自定义异常 public class Test { public static void main(String[] args) { int rest=1000;//余额只有1000 Scanner sc=new Scanner(System.in); System.out.println("请输入取款金额"); int money = sc.nextInt(); if(money<=rest){ rest-=money; System.out.println("取款成功"); }else { throw new Error("余额不足"); } } } class Error extends RuntimeException{ public Error(String mes) { super(mes); } } 运行结果: 请输入取款金额 1200 Exception in thread "main" demo2.Error: 余额不足 at demo2.Test.main(Test.java:14)
异常注意事项:
子类重写父类方法时,只能抛出父类异常的子集。
如果父类没有抛出异常,则子类也不能抛出异常,子类有异常只能用try-catch方法解决