java面向对象—4. 异常处理

目录

目标

什么是异常?

处理异常

try+catch的处理流程

finally

小结:

try-catch-finally 规则(异常处理语句的语法规则):

try、catch、finally语句块的执行顺序:

异常体系结构

throws关键字

throws抛出异常的规则:

throw关键字(用得少)

RuntimeExcepion与Exception的区别

常见的异常

1.runtimeException子类:

2.IOException

3. 其他

自定义异常类了解 (了解)

异常处理常见面试题 


目标

  1. 明确什么是异常 (重点)

  2. 能辨识出常见的异常及其含义。(熟悉+)

  3. 理解异常产生的原理 (了解

  4. 能处理异常 (重点)

  5. 能够自定义异常类型 (熟悉)

什么是异常?

异常是在程序中导致程序中断运行的一种指令流。 例如,现在有如下的操作代码:

public class ExceptionDemo01{    
    public static void main(String argsp[]){                
        int i = 10 ;        
        int j = 0 ;
        System.out.println("============= 计算开始 =============") ;        
        int temp = i / j ;  // 进行除法运算        
        System.out.println("temp = " + temp) ;        
        System.out.println("============= 计算结束 =============") ;    
    } 
};

运行结果: ============= 计算开始 =============

Exception in thread "main" java.lang.ArithmeticException: / by zero

at ExceptionDemo01.main(ExceptionDemo01.java:6)

以上的代码在“int temp = i / j ;”位置处产生了异常,一旦产生异常之后,异常之后的语句将不再执行了,所以现 在的程序并没有正确的执行完毕之后就退出了。

那么,为了保证程序出现异常之后仍然可以正确的执行完毕,所以要采用异常的处理机制。

 

处理异常

在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常。

一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的。

如果要想对异常进行处理,则必须采用标准的处理格式,处理格式语法如下:

try{    
// 有可能发生异常的代码段 
}catch(异常类型1 对象名1){    
// 异常的处理操作
}catch(异常类型2 对象名2){ 
// 异常的处理操作 } ... 
finally{    
// 异常的统一出口 
}

try+catch的处理流程

  1. 一旦产生异常,则系统会自动产生一个异常类的实例化对象。
  2. 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异 常抛出.
  3. 所有的catch根据方法的参数匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

finally

在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生 了异常,最终都要执行此段代码。

小结:

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。

try-catch-finally 规则(异常处理语句的语法规则):

1)  必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。
2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
3) catch 块与相应的异常类的类型相关。
4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块
5) 可嵌套 try-catch-finally 结构。
6) 在 try-catch-finally 结构中,可重新抛出异常。
7) 除了下列情况,总将执行 finally 做为结束:JVM 过早终止(调用 System.exit(int));在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。

try、catch、finally语句块的执行顺序:

1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

异常体系结构

异常指的是Exception , Exception类在Java中存在一个父类Throwable(可能的抛出)

Throwable存在两个子类:    

  1. Error:表示的是错误,是JVM发出的错误操作,只能尽量避免,无法用代码处理。    
  2. Exception:一般表示所有程序中的错误,所以一般在程序中将进行try…catch的处理。
     

  • 受检异常必须抛出去或者try-catch,否则飘红线
  • 非受检异常即运行时异常无论是否抛出去或者try-catch都不会飘红线

异常捕获的注意点:    

  1. 捕获更粗的异常不能放在捕获更细的异常之前。    
  2. 如果为了方便,则可以将所有的异常都使用Exception进行捕获

特殊的多异常捕获写法:
 
catch(异常类型1 |异常类型2 对象名){    

//表示此块用于处理异常类型1 和 异常类型2 的异常信息

//几个不同的异常使用相同的代码处理。

}

throws关键字

在程序中异常的基本处理已经掌握了,但是随异常一起的还有一个称为throws关键字,此关键字主要在方法的声明上使 用,表示方法中不处理异常,而交给调用处处理。
 
格式:    

返回值 方法名称()throws Exception{            

}

throws抛出异常的规则:

    1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。

    2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误

    3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。

    4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。

判断一个方法可能会出现异常的依据如下:
     1)方法中有throw语句。例如,以上method7()方法的catch代码块有throw语句。
     2)调用了其他方法,其他方法用throws子句声明抛出某种异常。

throw关键字(用得少)

 throw关键字表示在程序中人为的抛出一个异常,因为从异常处理机制来看,所有的异常一旦产生之后,实际上抛出 的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。        

代码: throw new Exception("抛着玩的。") ;
 

RuntimeExcepion与Exception的区别

注意观察如下方法的源码:  

       Integer类:   public static int parseInt(String text)throws NumberFormatException         

此方法抛出了异常, 但是使用时却不需要进行try...catch捕获处理,

原因:    因为NumberFormatException并不是Exception的直接子类,而是RuntimeException的子类,只要是 RuntimeException的子类,则表示程序在操作的时候可以不必使用try…catch进行处理,如果有异常发生,则由JVM进 行处理。当然,也可以通过try catch处理。

常见的异常

1.runtimeException子类:

    1、 java.lang.ArrayIndexOutOfBoundsException
          数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
    2、java.lang.ArithmeticException
         算术条件异常。譬如:整数除零等。
    3、java.lang.NullPointerException
         空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
    4、java.lang.ClassNotFoundException
         找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

   5、java.lang.NegativeArraySizeException  数组长度为负异常

   6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常

   7、java.lang.SecurityException 安全性异常

   8、java.lang.IllegalArgumentException 非法参数异常

2.IOException

IOException:操作输入流和输出流时可能出现的异常。

EOFException   文件已结束异常

FileNotFoundException   文件未找到异常

3. 其他

ClassCastException    类型转换异常类

ArrayStoreException  数组中包含不兼容的值抛出的异常

SQLException   操作数据库异常类

NoSuchFieldException   字段未找到异常

NoSuchMethodException   方法未找到抛出的异常

NumberFormatException    字符串转换为数字抛出的异常

StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常

IllegalAccessException  不允许访问某类异常

InstantiationException  当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

自定义异常类了解 (了解)

编写一个类, 继承Exception,并重写一参构造方法 即可完成自定义受检异常类型。 编写一个类, 继承RuntimeExcepion,并重写一参构造方法 即可完成自定义运行时异常类型。
例如:

class MyException extends Exception{    // 继承Exception,表示一个自定义异常类        
    public MyException(String msg){            
        super(msg) ;    
        // 调用Exception中有一个参数的构造        
    }    
};    
//自定义异常可以做很多事情, 例如:    
class MyException extends Exception{        
    public MyException(String msg){            
        super(msg) ;            
        //在这里给维护人员发短信或邮件, 告知程序出现了BUG。        
    }    
}

 

异常处理常见面试题 

1.  try-catch-finally 中哪个部分可以省略?

答:  catch和finally可以省略其中一个 , catch和finally不能同时省略    注意:格式上允许省略catch块, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码. 

2.  try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

答:finally中的代码会执行

详解:    执行流程:        

  1. 先计算返回值, 并将返回值存储起来, 等待返回        
  2. 执行finally代码块        
  3. 将之前存储的返回值, 返回出去;  

     需注意:      

  1. 返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不 会改变        
  2. finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或 catch中的值        
  3. 如果在try或catch中停止了JVM,则finally不会执行.例如停电- -, 或通过如下代码退出 JVM:System.exit(0);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值