Java异常处理
程序运行时发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。
异常发生时,是任程序自生自灭、立刻退出终止?
程序员真理
凡是程序一定会出错
-
出错不是问题,关键是出错之后,错误如何处理?谁处理?
-
程序可以从错误中恢复吗?恢复不了就崩溃么?
意外产生和处理过程概述
运行时有许多因素引起出错,硬件失败,除法溢出,数组下标越界。
出错的位置都在方法Method里
出错后方法生成一个Exception对象,并把它交给JVM。这个对象里包括许多信息:错误类型,错误位置。JVM负责处理Exception对象
public static void main(String[] args) {
int k=0;
System.out.println(10/k);
System.out.println("计算结果为: "+10/k);
}
//运行结果
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test1.main(Test1.java:6)
//其中ArithmeticException就是异常的类型,其后紧邻的就是异常的说明
//Test1.java:6告知出现问题的行
这种生成Exception对象并交给系统的过程叫抛出意外throwing an exception
public static void main(String[] args) throws Exception {
//在方法上声明可能会有的异常,由调用方进行处理
int k = 0;
if (k < 1)
throw new Exception("中国加油! ");//人为编程产生异常
System.out.println(10 / k);
System.out.println("计算结果为:" + 10 / k);
}
一个方法抛出意外后,JVM就试图在调用栈里找能处理这个类型Exception对象的方法。找到就执行,找不到程序中止
出错的处理方式
以前是正常流程代码和问题处理代码相结合。现在将正常流程代码和问题处理代码分离,以提高阅读性。
//伪代码
int res=func1(10,20);
if(res>0){
println(""正常执行结果! ");
}else if(res==0){
println(""程序太胖了,被卡住了!");
}else if(res<0){
println("程序太傻了,不知道怎么处理! ");
}
可以根据返回值判断程序的执行情况,如果>=0表示正常执行完毕,如果<0,则返回不同的负值表示不同的运行情况。调用方法时可以根据不同的返回值进行不同的处理
Java中引入异常对象的目的在于给调用方更加详细的出错说明,以达到异常处理和正常代码分离,并且按照不同的异常进行处理的目的
其实异常就是Java通过面向对象的思想将程序中的问题封装成了对象,用异常类对其进行描述。1、不同的问题用不同的类进行具体的描述。2、问题很多,意味着描述的类也很多,将其共性进行向上抽取就形成了异常体系
异常
Java异常是Java提供的用于处理程序中错误的一种机制
- 所谓错误是指在程序运行的过程中发生的一些异常事件。如:除0溢出、数组下标越界、所需要读取的文件不存在
- 设计良好的程序应该在异常发生时提供处理这些错误,使得程序不会因为异常的发生而阻断或者产生不可预见的结果
- Java程序的执行过程中如果出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并经被提交给Java运行时系统,这个过程称为抛出异常throw。比如:鲁棒性的问题
- 当Java运行时系统接收到异常对象时,代码的执行流程会自动中断,转向寻找能处理这一异常的代码并把当前异常对象交给其处理,这个过程称为捕获异常
Java异常处理的关键字有throws、throw、try、catch、finally共5个关键字
异常的用途
异常就是在程序运行时由代码所产生的不正常状态。换句话说,异常就是一个运行时不支持异常处理的计算机语言中,错误必须被人工进行检查和处理,这显然麻烦而低效
Java语言提供了异常处理机制,为方法的异常终止和出错处理提供了清楚的接口
- 用来在发生运行异常时告诉程序如何控制自身的运行,以防止错误的进一步恶化
- 每个方法必须对他可能抛出的异常进行预先声明,在定义方法时,必须声明这个方法可能会抛出哪一种或几种异常
异常的分类
JavaSE中定义了很多异常类,这些类可以对应各种各样可能出现的异常事件。
Throwable类是Java异常类型的顶层父类,一个对象只有是Throwable类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别
Java异常可以分为3大类
所有异常对象的父类为Throwable—Object
1、Error及其子类:错误,一般指的是虚拟机的错误,是由Java虚拟机生成并抛出,程序不能进行处理所以也不加处理,例如OutOfMemoryError内存溢出、调用栈溢出StackOverFlowError
OOM异常:
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
int[] arr = new int[Integer.MAX_VALUE];
System.out.println("OOM END...");
}
调用栈溢出StackOverFlowError
public static void main(String[] args) {
pp();
}
public static void pp() {
System.out.println("pp. . ..");
pp();
}
2、RuntimeException及其子类:运行时异常(非受检型异常),是由于编程bug所导致,希望越早发现越好,所以不进行处理,直接中断报错即可,编程人员针对报错信息修改程序bug来解决问题。
常见的第一种运行时异常:ArithmeticException算术异常,就是执行数学计算时产生的非正常情况。如除以0
常见的第二种运行时异常:NullPointerException空指针异常(试图访问null对象的引用)
常见的第三种运行时异常:IndexOutOfBoundsException下标出界
常见的第四种运行时异常:ClassCastException试图把一个对象转换成非法类型
常见的第五种运行时异常:NumberFormatException数据格式异常,一般出现在数据类型转换中
ArithmeticException算术异常
public static void main(String[] args) {
int k = 0 ;
System.out.println(10 / k);
}
解决方案:判断分母是否为0
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int k = sc.nextInt();
if (k == 0) {
System.out.println("除数不合法!");
}else
System.out.println(10 / k);
}
NullPointerException空指针异常
public static void main(String[] args){
Object obj = null;
System.out.println(obj); // string.valueof(x) x.tostring();
System.out.println(obj.tostring()) ;
}
解决方案:调用对象的方法之前先进行判空处理
public static void main(String[] args) {
Object obj = <