异常处理机制-Exception
异常类在java.lang包中。
抛出异常应该使用的关键字是throw.
1.异常的基本介绍
(1).定义
异常处理是java中重要的容错方式。为什么要进行异常处理呢?
容错:在程序设计时,要考虑周密,针对可能发生的意外进行预防措施,在程序上加上相应的处理指令。
异常:Java中处理错误的一种机制。
抛出异常:Java程序在执行过程中如果出现异常事件,可以生产一个异常对象,这个异常对象封装了异常信息,并被提交给运行时系统。
捕获异常:当运行时系统接收到异常对象时,会把当前的异常对象交由能处理这一异常的代码进行处理。(catch进行捕获异常。)
try{
//此处是抛出异常部分,但这个异常对象的抛出不是由程序的语句完成的,是JVM(虚拟机)完成的。
}catch(Exception e){
}
(2).异常的分类
Throwable类是Java语言中所有错误或异常的父类。Exception是所有异常的父类。
2.异常处理规则
异常捕获和处理是用try-catch-finally语句结构完成的。
(1)语句格式
try{
语句组1
}catch(异常类 1 对象名){
语句组2
}catch(异常类2 对象名){
语句组3
}
.......
}finally{
语句组4
}
解释:(1)try代码部分叫做try 语句块,(抛出异常部分),包含可能产生异常的代码,一个try语句块可以抛出一个或多个异常,catch进行捕获和处理。try不能脱离catch代码块或finally代码块而单独存在。try代码块后面至少有一个catch代码块或者finally代码块,但finally代码块只能是0个或1个。try代码块后面可以是try{ }catch{ },也可以是try{ }finally{ }.如果try代码块没有抛出异常,就会跳过catch语句块。
try 中某行代码抛出异常后,将终止下面的程序执行,转去对应的catch代码块进行处理异常(一次匹配成功则进行处理,,处理后的catch的其他类型语句就不再执行了,但是finally和其他语句要执行;如果一次不行,则一直匹配到成功;若所有的catch都没有匹配,则视为异常未处理,finally的语句可以执行,但finally代码块后面的程序不执行。)catch在这里就是个选择语句,选择相对应的异常类型进行执行
(2)catch 代码块进行异常的捕获和处理,每个try代码块后面可以跟一个或多个catch代码块,用来处理不同类型的异常对象,即格式为catch(异常类型 异常参数(相当于方法中的形参))。
catch代码块的异常对象封装了异常事件发生的信息,在catch语句块中可以使用异常对象的方法获取被封装的异常事件的发生:
getMessage():返回异常信息
printStackTrace():用来跟踪异常事件发生时执行堆栈的内容。经常出现的语句是
catch(Exception e){
e.printStackTrace();
}
写catch(异常类型 异常参数)时,必须子类异常在前,父类异常在后。catch 异常类型的排列顺序是从子类到父类排列,反之有错,且无意义。
(3)finally语句块就是为异常处理提供了一个出口,在finally代码块中进行资源清除工作,如关闭打开的文件,清除临时文件。无论try语句是否抛出异常,finally代码块都要执行。
注:finally代码块不执行的情况:先执行了System.exit();
如果catch语句块和finally语句块并存,则catch代码块必须在finally代码块的前面。
(4)throw e /throws
(2)方法调用时的异常处理
一个方法抛出异常,由上一级调用的此方法抛出,如无法处理,一直向上一级抛出,最后抛给main方法。如处理继续执行,否则就会程序中断。
异常前有return怎么处理,怎么运行的?
3.异常类的定义与使用
在写程序时,除了使用Java类库中的异常类外,有时需要在程序中根据具体情况定义一些异常类。
自己定义的异常类通常是Exception的子类,或是Throwable的子类或间接子类。
(1)定义异常类
class numException extends Exception{
//定义成员变量reason
private String reason;
//记录异常原因
public numException(String r)
rason = r;
}
//定义成员方法,getReason()返回异常原因
public String getReason(){
return (reason);
}
(2)创建并抛出异常对象
创建、抛出异常对象时在方法体中完成的,格式如下:
修饰符 返回类型 方法名(参数列表) throws 异常类名表
{
...
throw 异常对象;//出现在方法中,说明这个方法可能会抛出异常对象,那么在调用这个方法时要进行相应的异常捕获和处理。
}
当方法头部出现了“throws 异常类名表 ”,则必须进行相应的异常捕获处理,否则会出错。
实例:
NumExceptionText.java
package Exception;
//异常处理:学号位数不对,应该是九位
/*(1)首先自定义自己的异常,该异常继承Exception
* 为自己定义的异常设置成员变量,设置构造器,设置getReason()方法
*(2)设置非主类Student,在方法(void setStudent())中进行引用自定义的类抛出( throws numException),
*在方法体中设置,以及设置 throw new numException("抛出异常信息提示"
*(3)在主类中进行实例化,还有进行try(调用在非主类中设置的st.setStudent("传值")的方法传入值)-catch异常处理。
*/
class numException extends Exception{
private String reason;
public numException(String r) {
super();
this.reason = r;
}
public String getReason() {
return reason;
}
}
class Student{
private String studentNo,name;
void setStudent(String stuNo, String nm) throws numException {
if(stuNo.length()!=9)
throw new numException("学号位数不对,应该是9位!");
this.studentNo = stuNo;
this.name = nm;
}
void showInfo(){
System.out.println("学号:"+this.studentNo);
System.out.println("姓名:"+this.name);
}
}
public class NumExceptionTest {
public static void main(String[] args) {
Student st = new Student();
try{
st.setStudent("12345678","张三"); //错误的信息,会抛出异常
//st.setStudent("123456789", "张三"); // 正确的信息会输出学号和姓名
}catch(numException e){
System.out.println(e.getReason());
}
st.showInfo();
}
}
邮政编码的异常处理
customerTest.java
package Exception;
class AddressException extends Exception{
private String reason;
public AddressException(String r) {
super();
this.reason = r;
}
public String getReason() {
return reason;
}
}
class Customer{
private String name;
private String Address;
private String emailnumAddess;
void setCustomer(String nm,String ad,String enumd) throws AddressException{
if(enumd.length()!= 6)
throw new AddressException("邮政编码必须是6位数字!");
this.name = nm;
this.Address = ad;
this.emailnumAddess = enumd;
}
void showInfo(){
System.out.println("姓名:"+this.name);
System.out.println("地址:"+this.Address);
System.out.println("邮政编码:"+this.emailnumAddess);
}
}
public class customerTest {
public static void main(String[] args) {
Customer c = new Customer();
try{
c.setCustomer("李四", "海棠路", "123456");
}catch(AddressException e){
System.out.println(e.getReason());
}
c.showInfo();
}
}