黑马程序员---7、异常类
2013-07-25 18:10
225 查看
异常类
1、异常(Exception)概念
从字面理解,异常(Exception)就是超出了程序员预计的某些特殊情况,不在正常的情况之列。在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。
Throwable 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Exception(异常)是应用程序中可能的可预测、可恢复问题。一般大多数异常表示中度到轻度的问题。异常一般是在特定环境下产生的,通常出现在代码的特定方法和操作中。在 EchoInput 类中,当试图调用 readLine 方法时,可能出现 IOException 异常。
Error(错误)表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。
Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。
下图是java异常的类层次结构图:
【例】认识异常
public class ExceptionDemo2 {
public static void main( String args[ ] ){
int a = 0;
System.out.println( 5/a );
}
}
程序运行结果如下:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionDemo2.main(ExceptionDemo2.java:5)
1、处理异常
在 Java 应用程序中,使用try-catch-finally语句来捕获并处理异常。其语法结构如下:
try{
…… //可能会产生异常的程序代码
}
catch(Exception_1 e1){ //处理异常Exception_1的代码 }
catch(Exception_2 e2){ //处理异常Exception_2的代码 }
……
catch(Exception_n en){ //处理异常Exception_n的代码 }
[finally{ //通常是释放资源的程序代码}]
【例】异常处理1
public class ExceptionDemo2 {
public static void main
4000
( String args[ ] ){
int a = 0;
try{
System.out.println( 5/a );
}catch ( Exception e){
System.out.println("处理异常!");
}finally{
System.out.println("finally!");
}
}
}
其中:
(1)try 块:将一个或者多个语句放入 try 时,则表示这些语句可能抛出异常。编译器知道可能要发生异常,于是用一个特殊结构评估块内所有语句。
(2)catch 块:当问题出现时,一种选择是定义代码块来处理问题,catch 块的目的便在于此。catch 块是 try 块所产生异常的接收者。基本原理是:一旦生成异常,则 try 块的执行中止,JVM 将查找相应的 JVM。
(3)finally 块:还可以定义 finally 块,无论运行 try 块代码的结果如何,该块里面的代码一定运行。在常见的所有环境中,finally 块都将运行。无论 try 块是否运行完,无论是否产生异常,也无论是否在 catch 块中得到处理,finally 块都将执行。
(4)try-catch-finally 规则:
必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。
(5)必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
(6)catch 块与相应的异常类的类型相关。
(7)一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。
(8)可嵌套 try-catch-finally 结构。
2、声明异常
声明抛出异常是一个子句,必须加在方法头部的后边。其格式如下:throws <用逗号分隔的异常列表>
若一个方法中声明抛出异常,则表示该方法可能会抛出所声明的那些异常,从而要求该方法的调用者,在程序中对这些异常加以注意和处理。若一个方法没有抛出异常,该方法仍可能会抛出异常,只不过这些异常不需要调用者注意。通常,<用逗号分隔的异常列表>中的异常,都是要求调用者一定要在程序中明确加以处理的。或者是用try-catch-finally捕获处理,或者再次声明抛出异常。
【例】从键盘读入汉字,打印其机内码。
import java.io.IOException;
public class ExceptionDemo {
public static void main ( String args[ ] )throws IOException{
int c;
while((c=System.in.read())!=-1)
System.out.println(c);
}
}
因为System.in.read()方法会抛出IOException异常,而程序中没有用try-catch-finally捕获处理,所以必须在main()方法的头部加上throws IOException,明确表示对该异常,程序不想处理,交由调用者处理,main()方法的调用者是JVM,一旦有异常,程序即运行结束。
3、 抛出异常
声明抛出异常是一个说明性的子句,只是表示一个方法可能会抛出异常,而真正抛出异常的动作是由抛出异常语句来完成的。其格式如下:throw <异常对象>;
其中,<异常对象>必须是Throwable类或其子类的对象。
【例】计算一个数字的平方根,以字符串的形式提供数字,当用户输入的字符串为空,或者字符串无法转换成数字,或者转换成的数字小于0,都会抛出异常
public class ThrowAndThrows {
public static double sqrt(String nStr) throws Exception{
if (nStr == null){
//用throw关键字抛出异常,当异常被抛出时,程序会跳出该方法
throw new Exception("输入的字符串不能为空!");
}
double n = 0;
try {
n = Double.parseDouble(nStr);
//arseDouble方法可能抛出异常NumberFormatException
} catch (NumberFormatException e){
//将捕获的异常重新封装并抛出
throw new Exception("输入的字符串必须能够转化成数字!", e);
}
if (n < 0){
throw new Exception("输入的字符串转化成的数字必须大于等于0!");
}
return Math.sqrt(n);//计算平方根
}
public static void main(String[] args) {
try{
ThrowAndThrows.sqrt("-124.56");
} catch (Exception e){//将sqrt方法声明的可能抛出的Exception异常捕获。
//打印捕获的异常的堆栈信息,从堆栈信息中可以发现异常发生的位置和原因。
System.out.println("Got a Exception: " + e.getMessage());
e.printStackTrace();
}
}
}
4、 定义自己的异常
自定义的异常类必须是Throwable类的子类,通常是从Exception类或其子类继承。
【例】在定义银行类时,若取钱数大于余额时需要做异常处理。定义一个异常类 insufficientFundsException。取钱(withdrawal)方法中可能产生异常,条件是余额小于取额。
处理异常在调用 withdrawal 的时候,因此 withdrawal 方法要声明抛出异常,由上一级方法调用。
//异常类
class InsufficientFundsException extends Exception{
private Bank excepbank; // 银行对象
private double excepAmount; // 要取的钱
InsufficientFundsException(Bank ba, double dAmount)
{ excepbank=ba;
excepAmount=dAmount;
}
public String excepMessage(){
String str="The balance is"+excepbank.balance
+ "\n"+"The withdrawal was"+excepAmount;
return str;
}
}
//银行类
class Bank{
double balance;// 存款数
public Bank(double balance){
this.balance=balance;
}
public void deposite(double dAmount){
if(dAmount>0.0) balance+=dAmount;
}
public void withdrawal(double dAmount)
throws InsufficientFundsException{
if (balance<dAmount) throw new InsufficientFundsException(this, dAmount);
balance=balance-dAmount;
}
public void showBalance(){
System.out.println("The balance is "+(int)balance);
}
}
//前端调用
public class ExceptionDemo4 {
public static void main(String[] args) {
try{
Bank ba=new Bank(50);
ba.withdrawal(100);
System.out.println("Withdrawal successful!");
}catch(InsufficientFundsException e) {
System.out.println(e.toString());
System.out.println(e.excepMessage());
}
}
}
Java 异常处理是使用 Java 语言进行软件开发和测试脚本开发中非常重要的一个方面。对异常处理的重视会使开发出的代码更健壮,更稳定。本节系统的阐述了 Java 异常处理的原理和方法。能帮助读者更加清楚的理解 Java 异常处理机制,在开发代码时更加灵活的使用它。
相关文章推荐
- 黑马程序员——Java基础 异常机制 (复习)
- 黑马程序员Java面向对象——异常
- 黑马程序员-javaSE学习之异常
- 黑马程序员-JAVASE入门(异常)
- 黑马程序员——Java基础:内部类、异常、包
- 黑马程序员——Java基础---异常、IO流
- 黑马程序员--异常总结
- 黑马程序员——Java异常类笔记
- 29.黑马程序员-异常
- 黑马程序员_异常(一)
- 黑马程序员 Java基础知识总结-异常处理
- 黑马程序员——异常
- [黑马程序员]异常类
- 黑马程序员_异常体系
- 黑马程序员——Java语言基础:异常、包
- 黑马程序员——Java基础--异常
- 黑马程序员——集合取方法和异常的继承体系
- 黑马程序员——多态,内部类,异常
- 黑马程序员-day10-面向对象(异常)
- 黑马程序员———Java基础——异常概述