1.异常的概念
异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序.也称为例外.
2.错误的分类
•通常程序中的错误可分为三种类型:
1.编译错误:编译器能够检测到的错误,一般是语法错误。此时不能将源代码(.java)编译成可执行的字节码文件(.class)。
2.运行错误:程序运行时产生的错误,例如被0除、数组下标越界等等。
3.逻辑错误:这是机器本身无法检测的,需要程序员对运行结果及程序逻辑进行分析才能发现,逻辑错误可能会导致运行结果错误,有时也可能会导致运行错误。
3.异常处理机制的概念
1.异常又称为例外,是特殊的运行错误对象。
2.程序在运行期间可能会遇到一些非预期的或不正常的错误,这些错误将会阻止程序的正常运行。
3.当发生异常时,系统中需要有一个相应的机制来处理它,确保程序可以继续正常运行,而不会产生死机、死循环或其他对操作系统的损害,从而保证整个程序运行的安全性。这就是异常处理机制。
4.应用Java的异常处理机制,在程序出现异常时,程序员可以捕获该异常,并进行相应的处理。
4.Java中的错误类型
1.在Java中有两种类型的错误:Exception类(异常)和Error类(错误)。
2.Exception类是所有异常类的父类,包括了一些由程序本身及环境所产生的错误。应用Java的异常处理机制,异常(Exception)可以被捕获并进行相应的处理。例如数组下标越界、被0除等等。
3.Error类则包括了一些较少发生的内部系统错误。这些错误都是严重的错误,用户程序无法进行处理,只能通知使用者关闭程序。例如内存不足、虚拟机内部错误等等。
4.Exception类和Error类都是Throwable类的子类。
•对于具体的异常,不应该使用Throwable类,而应该使用Exception或Exception的子类。
5.Java的预定义异常
1.ClassNotFoundException:无法找到指定的类时发生该异常。
2.FileNotFoundException:访问一个不存在的文件时发生该异常。
属于IOException
1.IOException:通常的I/O错误。
2.ArithmeticException:
–如果除数为0,则发生该异常。例:int i =12 / 0;
3.NullPointerException:
–对象未实例化时访问该对象则发生该异常。
–例:int[] a= null;
a.toString();
4.ArrayIndexOutOfBoundsException:
–数组下标越界异常。例:int[] a= { 1 }; a[1] = 2;
2.3.4属于RuntimeException
5.NumberFormatException:
–数字格式化异常。例:Integer.parseInt("abc");
6.异常的发生
1.异常的发生有两种情况:
–系统自动抛出异常。一般是由于编程错误或者数据错误而导致的异常。
–显式使用throw语句抛出异常。
2.显式抛出异常的步骤:
–使用new创建异常类的对象,该对象类型是Exception或Exception的子类。
–使用throw语句抛出异常。
7.异常的捕获和处理
1.使用try{}catch{}块捕获异常
2.语法:try {
可能会发生异常的代码
} catch(异常类型异常变量名) {//
捕获例外
异常处理代码 // 处理异常
}
3.发生的异常类型与catch中异常的类型相同则可以被捕获
4.发生的异常类型是catch中异常的类型的子类也可以被捕获
5.如果try部分的代码没有发生错误,catch块的代码不会执行
6.如果一段代码肯定不会发生异常,则可以不用try{}catch{}块
7.嵌套时内层的catch捕捉的异常类型不能外层异常的父类。
8. 多个异常的捕获和处理
1.可用一组并列的catch块处理多个异常的情况
2.语法:try {
可能会发生异常的代码
} catch(异常类型1
异常变量名) {
异常处理代码
} catch(异常类型2
异常变量名) {
异常处理代码
}
……
3.注意点:
–按从上到下顺序捕获(注意排列顺序)
多个catch块中,如果异常类型没有父子关系,则catch块的顺序可以随意,如果有父子关系,则子类catch块必须写在前面,父类catch块写在后面
9.异常处理过程
1.当遇到关键字“throw”时就抛出一个例外
2.将控制转移到相关的“catch”块中处理
3.如果产生异常的方法没有处理该异常的“catch”语句块,则继续将该异常往外抛
4.退出当前方法并转向上一级调用此方法的方法的“catch”语句块
5.若始终没有“catch”块来处理该异常则由运行系统处理
10.非检查型异常和检查型异常
1.非检查型异常:
–所有继承自RuntimeException的异常称为非检查型异常。
–编译器对非检查型异常不做编译检查。
2.检查型异常:
–非检查型异常以外的异常称为检查型异常。
–方法中可能抛出的检查型异常必须在方法定义部分使用throws语句进行声明。
–对于任何方法,如果它调用的方法会抛出一个检查型异常,那么调用者就必须捕获该异常或者也在方法定义部分使用throws语句声明会抛出该类型的异常。
–如果未捕获该异常也未使用throws声明会发生编译错误。
(只有RunTimeException才可以不用显示的throws出来,即在方法头部写出,其他的异常则必须显示的抛出)
11.Exception类的常用方法
1.StringgetMessage():返回异常的详细信息
2.StringtoString():返回异常的描述,包括类名、详细信息
3.void printStackTrace():打印出异常发生的路径,以及引起异常的方法调用的序列
12. 自定义异常
1.除了使用系统预定义的异常类外,还可以声明自己的异常类。
2.自定义异常必须继承自Exception或Exception的子类。
3.可以在自定义异常类中添加构造方法、成员变量和成员方法。
4.语法:
class 类名extends异常类名{
// 成员变量、成员方法
}
13.finally
1.finally:不论是否有异常发生,finally中的代码都要执行
2.作用:用于非内存的系统资源的释放,如关闭打开的文件、关闭数据库连接等等。
3.语法:try {
……
} catch(异常类名e){
……
} finally {
……
}
14.异常处理的嵌套
1.finally:不论是否有异常发生,finally中的代码都要执行
2.作用:用于非内存的系统资源的释放,如关闭打开的文件、关闭数据库连接等等。
3.语法:try {
……
} catch(异常类名e){
……
} finally {
……
}
练习
1.设计一个异常类FlowException,该类继承自Exception,getMsg()方法返回错误信息。(格式:id的值:msg的值)
2.定义一个异常测试类ExceptionTest
–定义一个方法test,该方法接收2个整型的参数num1和num2,如果num1
- num2<=0,则抛出异常FlowException,错误信息为“404:UnderValueErr”;如果num1-
num2 >= 1000,则抛出异常FlowException,错误信息为”405:OverValue
Err”
在main方法中通过键盘输入2个数,测试方法test并显示错误信息。
代码
package com.hisoft.java.exceptiondemo;
import java.util.Scanner;
/**
*
* @author MR.Ren
* @data 2018年1月30日下午5:22:26
* @className FlowException.java
*/
public class FlowException extends Exception {
private static final long serialVersionUID = 1L;
private int id;// 定义成员变量id
private String msg;// 定义成员变量msg
public FlowException(int id, String msg) {// 有参构造方法并初始化
this.id = id;
this.msg = msg;
}
// getMsg()方法返回错误信息
public String getMsg() {
return id + ":" + msg;
}
}
// 异常测试类
class ExceptionTest {
public static int test(int num1, int num2) throws FlowException {
if (num1 - num2 <= 0) {
throw new FlowException(404, "Under Value Err");// 抛出异常信息
}
if (num1 - num2 >= 1000) {
throw new FlowException(405, "Over Value Err");// 抛出异常信息
}
return num1 - num2;
}
public static void main(String[] args) {
// 使用try--catch处理异常
try {
Scanner sc = new Scanner(System.in);
System.out.print("num1 = ");
int num1 = sc.nextInt();
System.out.print("num2 = ");
int num2 = sc.nextInt();
test(num1, num2);
sc.close();
} catch (FlowException e) {
System.out.println(e.getMsg());
e.printStackTrace();
}
}
}