黑马程序员---异常处理总结

---------------------- Java开发Android培训、期待与您交流! ----------------------


1、异常:

  • 无法穷举所有的异常错误,异常的情况往往要多于考虑到的情况,总有“漏网之鱼”存在,程序不够健壮。
  •  错误处理代码和业务实现代码混杂,严重影响代码的可读性,增加代码的维护难度。

2、异常处理的优点:

  • 把各种不同类型的异常进行分类,用Java类来表示异常情况,这种类被称为异常类
  • 异常流程的代码和正常流程的代码分离,提高程序的可读性。
  • 可以灵活处理异常,如果当前方法有能力处理异常,就捕获并处理它,否则只需抛出异常。

3、Java虚拟机的方法调用栈

Java虚拟机用方法调用栈来跟踪每个线程中一系列的方法调用过程。该堆栈保存了每个调用方法的本地信息(比如方法的局部变量)。每个线程都有一个独立的方法调用栈。对于Java应用程序的主线程,堆栈底部是程序的入口方法main()。当一个新方法被调用是,Java虚拟机把描述该方法的栈结构置入栈顶,位于栈顶的方法为正在执行的方法。

如果方法中代码块可能抛出异常,有如下两种处理办法:

(1) 在当前方法中通过try…catch语句捕获并处理异常。

(2) 在方法的声明处通过throws语句声明抛出异常。

当一个方法正常执行完毕,Java虚拟机会从调用栈中弹出该方法的栈结构,然后继续处理前一个方法。

4、异常处理机制

4.1 使用try…catch捕获异常

try {

  业务实现代码

} catch () {

 // 异常处理

 

}

  1.  如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,该异常对象被提交给Java运行时环境,这个过程被称为抛出异常。
  2.  当Java运行时环境收到异常对象时,会寻找能处理该异常对象的catch块,如果找到合适的catch块并把该异常对象交个该catch块处理,这个过程成为捕获异常。如果Java 运行时环境找不到捕获异常的catch块,则运行时环境终止,Java程序也将退出。
  3. 不管程序代码块是否处于try中,设置包括catch中,只要执行该代码块时出现了异常,系统都会生成一个异常对象。

例子1:ExceptionDemo01.java

String inputStr = null;

//br.readLine():每当在键盘上输入一行内容按回车,刚输入的内容将被br读取到。

while ((inputStr = br.readLine()) != null) {

try {

//将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串

String[] posStrArr = inputStr.split(",");

//将2个字符串转换成用户下棋的座标

int xPos = Integer.parseInt(posStrArr[0]);

int yPos = Integer.parseInt(posStrArr[1]);

//把对应的数组元素赋为"●"。

if (!gb.board[xPos - 1][yPos - 1].equals("╋"))

{

System.out.println("您输入的座标点已有棋子了,请重新输入");

continue;

}

gb.board[xPos - 1][yPos - 1] = "●";

} catch (Exception e) {

System.out.println("您输入的座标不合法,请重新输入。下棋座标应以x,y的格式");

continue;

}

gb.printBoard();

System.out.println("请输入您下棋的座标,应以x,y的格式:");

}

  1.  每个catch块都是专门用于处理该异常类及其子类的异常实例。
  2.  当Java运行时环境接收到异常对后,会依次判断对象是否是catch块后异常类或其子类的实例,如果是,Java运行时环境将调用该catch块来处理该异常;否则再次拿该异常对象和下一个catch块里的异常类进行比较。
  3. try块后可以有多个catch块,try块后使用多个catch块是为了针对不同异常类提供不同的异常处理方式。当系统发生不同的意外情况时,系统会生成不同的异常对象,Java运行时环境就会根据异常对象所属的异常类来决定使用哪个catch块来处理异常。
  4.  通常情况下,如果try块被执行一次,则try块后只有一个catch块会被执行,绝对不可能有多个catch块被执行。
  5. try块、catch块后面的{}不能省略。
  6. try块里面声明的变量是代码块内局部变量,它只在try块内有效,catch块中不能访问该变量。

4.2 异常继承



例子2ExceptionDemo02.java

public class ExceptionDemo02 {

public static void main(String[] args) {

try {

int a = Interger.parseInt(args[0]);

int b = Interger.parseInt(args[1]);

int c = a / b;

System.out.println("您输入的两个数相除的结果是:" + a / b);

} catch (IndexOutOfBoundsException ie) {

System.out.println("数组越界:运行程序时输入的参数个数不够");

} catch (NumberFormatException ne) {

System.out.println("数字格式异常:程序只能接受整数参数");

} catch (ArithmeticException ae) {

System.out.println("算术异常");

} catch (Exception e) {

e.printStackTrace();

System.out.println("未知异常");

}

}

}


4.3 访问异常信息

异常的几个常用方法:

  • getMessage(): 返回该异常的详细描述字符串。
  • printStackTrace(): 将该异常的跟踪站信息输出到标准错误输出。
  • printStackTrace(PrintStream s): 将该异常的跟踪站信息输出到指定输出流。
  • getStackTrace(): 返回该异常的跟踪站信息。

 例子3:ExceptionDemo03.java

import java.io.*;

public class ExceptionDemo03 {

public static void main(String[] args) {

try {

FileInputStream fis = new FileInputStream("a.txt");

} catch(IOException ioe) {

System.out.println(ioe.getMessage());

ioe.printStackTrace();

}

}

}



4.4 使用finally回收资源

如果try中打开了一些物理资源,如数据库连接、网络连接、磁盘文件等,这些物理资源必须显示回收。(Java的垃圾回收机制不回收任何物理资源,只回收堆内存中得对象所占用的内存。)

为了保证一定能够回收try中打开的物理资源,异常处理提供了finally块。(回收代码为什么一定要在finally中保证回收?)

例子4:ExceptionDemo04.java

import java.io.*;

public class ExceptionDemo04 {

public static void main(String[] args) {

FileInputStream fis = null;

try {

fis = new FileInputStream("a.txt");

} catch(IOException ioe) {

System.out.println(ioe.getMessage());

return;

//System.exit(1);

} finally {

if(fis != null) {

try {

fis.close();

} catch(IOException ioe){

ioe.printStackTrace();

}

}

System.out.println("finally is over!");

}

}

}

4.5 throws子句:声明可能会出现的异常

如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。

一个方法可能会出现多种异常,throws子句允许声明抛出多个异常,例如:

public void method() throws SQLException, IOException {…}

4.6 throw语句:抛出异常

throw语句用于抛出异常。

throw语句抛出的对象必须是java.lang.Throwable类或者其子类的实例。以下是非法的:

throw new String(“程序异常!”);

4.7 异常处理语句的语法规则

异常处理语句主要涉及到try、catch、finally、throw、throws关键字,要正确使用它们,必须遵守必要的语法规则。

try代码块不能脱离catch代码块finally代码块单独存在。

try代码块后面可以有零个或多个catch代码块,还可以有零个或至多一个finally代码块。如果catch代码块和finally代码块并存,finally必须在catch之后。

try代码块后面可以只跟finally代码块。

在try代码块中定义的变量的作用域为try代码块,在catch代码块和finally代码块中不能访问该变量。如:

public class Example {

    public static void main(String[] args) {

        try {

            int a = 1;

            new Example().methodA(a);

        } catch (SpecialException e) {

            a = 0;  //编译错误

        } finally {

            a++;    //编译错误

        }

    }

 

    public void methodA(int val) throws SpecialException{

 

    }

}



public class SpecialException extends Exception{

}


 

 

public class Example {

    public static void main(String[] args) {

        int a = 1;

        try {

            new Example().methodA(a);

        } catch (SpecialException e) {

            a = 0;  //编译错误

        } finally {

            a++;    //编译错误

        }

    }

 

    public void methodA(int val) throws SpecialException{

 

    }

}

Throw语句后面不允许紧跟其他语句,因为这些语句永远不会被执行。


---------------------- Java开发Android培训、期待与您交流! ----------------------详细请查看:www.itheima.com




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值