Java语言程序设计第五讲,异常处理

学习Java变成过程中我们遇到过许多程序报错现象

之后我们会查看报错原因,对代码进行有针对性的修改从而使其恢复正常

 

这就是异常处理的目的和用途:计算机提供准确的错徐信息,操作者则根据实际情况提供错误的应对策略与手段

 

在具体学习异常之前先来了解一下Java的异常处理机制:

1,操作者把可能会发生错误的代码放进try语句块中

2,当程序检测到出现了一个错徐时会抛出一个异常对象,异常处理代码会捕获并处理这个错误(catch语句块中的代码用于处理错误)

3,当异常发生时,程序控制流程有try语句跳转到catch语句块

4,不管是否有异常发生,finally语句块中的语句始终保证被执行

5,如果没有提供合适的异常处理代码JVM会结束掉整个应用程序

 

异常大体可以分为Error和Exception

Error一般指系统报错,比如打印时没有连接打印机等,通常由JVM处理

Exception又可以分为两类,Check异常和Runtime异常

Check异常是直接派生自Exception的异常,必须被捕获或再次声明抛出

Runtime异常是派生自RuntimeException的异常,使用throw语句可以随时抛出这种异常对象

 

assert语句允许程序在运行过程中判断某个条件是否满足,不满足时抛出AssertionError

例子: int i = 3;assert i == 10;//抛出异常

OOM Error 指系统内存不足

浮点数在进行除法时允许出现3.7/0,会抛出infinity但是程序继续执行

 

代码:

public class Main {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch");
}

throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("发生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch");
}
}
}

运行结果:

 

 

系统捕获ArrayIndexOutOfBoundsException();异常后跳转到catch执行System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch");语句,之后捕获ArithmeticException();异常,跳转到catch执行System.out.println("发生ArithmeticException");语句

代码:

public class Main {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArithmeticException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("发生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch");
}
}
}

运行结果:

 

 

系统捕获ArrayIndexOutOfBoundsException();异常后为找到与之匹配的catch,于是跳转到外层寻找与之匹配的catch,执行System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch");语句 

代码:

public class Main {
public static void main(String args[]) {
int result;
try {
System.out.println("in Level 1");
try {
System.out.println("in Level 2");
// result=100/0; //Level 2
try {
System.out.println("in Level 3");
result=100/0; //Level 3
}
catch (Exception e) {
System.out.println("Level 3:" + e.getClass().toString());
}
finally {
System.out.println("In Level 3 finally");
}
// result=100/0; //Level 2
}
catch (Exception e) {
System.out.println("Level 2:" + e.getClass().toString());
}
finally {
System.out.println("In Level 2 finally");
}
// result = 100 / 0; //level 1
}
catch (Exception e) {
System.out.println("Level 1:" + e.getClass().toString());
}
finally {
System.out.println("In Level 1 finally");
}
}
}

运行截图:

 

 

 在第三层遇到result=100/0;并抛出异常之后调用catch输出System.out.println("Level 3:" + e.getClass().toString())语句,之后catch语句不再执行,执行完所有的finally语句后结束程序运行

特别,当有多层finally语句嵌套时,异常在不同层次抛出,在不同位置抛出,肯导致不同的finally语句执行顺序

例如上一段代码如果异常在level2 抛出,则运行结果为:

 

 代码:

public class Main {
public static void main( String args[] ) {
try {
method1();
}
catch ( Exception e ) {
System.err.println( e.getMessage() + "\n" );
e.printStackTrace();
}
}
public static void method1() throws Exception {
method2();
}
public static void method2() throws Exception {
method3();
}
public static void method3() throws Exception {
throw new Exception( "Exception thrown in method3" );
}
}

运行结果:

 

 说实话看到运行结果的时候有被吓到……

言归正传,method1();抛出异常,之后printStackTrace()按照method1();被调用的吮吸一次抛出异常路径

 

在throws语句中声明的异常成为受控的异常,通常直接派生自Exception类

RuntimeException(其基类为Exception)和Error(其基类为Throwable)称为非受控的异常,这种异常不用在throws语句中声明

一个方法可以抛出多个受控的异常,此时在此方法调用语句处只要catch其中任何一个异常代码就可以顺利编译

子类的throws语句抛出的异常不能是其基类同名方法抛出的异常对象的父类

public class CatchWho {     public static void main(String[] args) {         try {             try {                 throw new ArrayIndexOutOfBoundsException();             }             catch(ArrayIndexOutOfBoundsException e) {                System.out.println(  "ArrayIndexOutOfBoundsException" +  "/内层try-catch");             }             throw new ArithmeticException();         }         catch(ArithmeticException e) {             System.out.println("发生ArithmeticException");         }         catch(ArrayIndexOutOfBoundsException e) {            System.out.println(  "ArrayIndexOutOfBoundsException" + "/外层try-catch");         }     } }
posted @   椰子灰  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示