五、异常

异常概念总结:

  练习一:异常的体系
   问题:
   1. 请描述异常的继承体系
   2. 请描述你对错误(Error)的理解
   3. 请描述你对异常(Expection的理解)
   4. 请描述你对运行时异常(RuntimeException)的理解

   答:

   1. 异常继承体系为:异常的根类是 java.lang.Throwable,其下有两个子类:
   java.lang.Error 与 java.util.Exception 。而Exception又分为编译时期异常:checked异常,与运行时期异常:runtime异常。 
   2. Error:表示不可修复的恶性的错误,只能通过修改代码规避错误的产生,通常是系统级别的,所以很严重。
   3. Exception:表示可修复的良性(相对于错误)的异常,异常产生后程序员可以并且应该通过代码的方式纠正,使程序继续运行,是必须要处理的。
   4. 运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。

  练习二:throw与throws的区别
   问题:
   1. 请描述throw的使用位置,作用是什么?
   2. 请描述throws的使用位置,作用是什么?

   答:
   1. throw关键字通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。
   2. throws关键字通常被应用在声明方法时,用来指定可能抛出的异常。多个异常可以使用逗号隔开。当在主函数中调用该方法时,如果发生异常,就会将异常对象抛给方法调用处。

  练习三:异常的处理方式
   问题:
      1. 异常处理方式有几种,分别是什么?
      2. 详细阐述每种方式对异常是如何处理的
   答:
   1. 异常的处理方式有两种,分别是使用throws和try...catch...finally
   2. throws用在方法的声明上后接异常类名,是把异常抛给调用者进行处理
   3. try...catch...finally是捕获异常,自己处理,处理完毕后面的程序可以继续运行
   a) try代码块中是可能出现异常的代码
   b) catch代码块,是遇到异常,对异常进行处理的代码
   c) finally代码块是无论是否发生异常,都必须执行的代码,用于释放资源.


   练习四:常见异常,及产生原因
   问题:请列举常见异常,并说明产生原因。

   答:
   NullPointerException:空指针异常。
    当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度等等。
   ArrayIndexOutOfBoundsException:数组索引越界异常。
   当对数组的索引值为负数或大于等于数组大小时抛出此异常。
   ArithmeticException:算术运算异常。
    程序中出现了除以零这样的运算就会出这样的异常,对这种异常,大家就要好好检查一下自己程序中涉及到数学运算的地方,公式是不是有不妥了。
   NumberFormatException:数字格式异常。
    当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。


1.异常:

  
  介绍:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
  在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理
  
  notes:
   异常指的并不是语法错误,语法错误的话 编译不通过,不会产生字节码文件,根本不能运行。
  
  ①异常体系:
       API:
    异常机制其实就是帮助我们找到程序中的问题,
    异常的根类是 
     java.lang.Throwable,下面有两个子类,
      -java.lang.Error (工程师不能处理,只能尽量避免)
      -java.util.Exception (由于使用不当导致,可以避免的)
    平常所说的异常就是java.util.Exception
   
  
  ②Throwable中的常用方法:
       ⑴打印异常的详细信息
   public void printStackTrace():
    包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
       ⑵获取发生异常的原因
   public String getMessage():
    提示给用户的时候,就提示错误原因。
       ⑶获取异常的类型和异常描述信息(不用)
   public String toString():
  ③异常的分类
   ⑴编译时期的异常:checked异常.在编译时期,就会检查,如果没有处理异常,则编译失败(如日期格式化异常)
   ⑵运行时期异常:runtime异常.在运行时期,检查异常,在编译时期,运行异常不会编译器检测(不报错)(如数学异常)
   

2.处理异常

      五大关键字: try catch finally throw throws
  ①抛出异常throw
   ⑴格式:
    throw new 异常类名(参数)

⑵抛出异常告诉调用者 :

    步骤1:创建一个异常对象.封装好一些提示信息(信息可以自己编写)
     throw new NullPointerException("要访问的arr数组不存在");
    步骤2:告知调用者,通过throw抛出一个异常对象,传递到调用者处,并结束当前方法的执行
     例子:
          public static void main(String[] args) {
        int[] arr = {2,4,52,2};
        int index = 4;
        int element = getElement(arr, index);

        System.out.println("element = " + element);
        System.out.println("over");


       }

       private static int getElement(int[] arr, int index) {
        // 判断 索引是否越界
        if (index<0||index>arr.length-1){
         // 如果越界 当执行完 throw 抛出异常随心后,方法无法继续运算

         // 这时就会结束当前方法的执行,并将异常 告知 调用者 这时就需要通过异常来解决

         throw new ArrayIndexOutOfBoundsException("数组越界");
        }
        int element = arr[index];

        return element;
       }
     结果:  
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 数组越界l~~~
      at DemoThread.ThrowTest.getElement(ThrowTest.java:22)
      at DemoThread.ThrowTest.main(ThrowTest.java:7)
   
  ②Objects非空判断
   还记得我们学习过一个类Objects吗,曾经提到过它由一些静态的实用方法组成,
   这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),
   那么在它的源码中,对对象为null的值进行了抛出异常操作。
   public static <T> T requireNonNull(T obj):查看指定引用对象不是null。
   
   public static <T> T requireNonNull(T obj) {
    if (obj == null)
     throw new NullPointerException();
    return obj;
   }
  ③声明异常throws
   说明:
    将问题标识出来,报告给调用者,如果方法内通过throw抛出了编译时异常,而没有捕获处理,那么必须同throws进行声明
   让调用者去处理.
   关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常
   格式:
    修饰符 返回值类型 方法名(参数) throws 异常类名1 ,异常类名2...{}
    
   例子:
        public static void main(String[] args) throws FileNotFoundException {
      read("a.txt");
     }
     // 如果定义功能时 有问题 发生需要报告给调用者,可以通过在方法上使用throws关键字进行声明
     public static void read(String path) throws FileNotFoundException{
      if (!path.equals("a.txt")){
       // 假设 如果不是a.txt认为 该文件不存在 是一个错误 也就是异常 throw
       throw new FileNotFoundException("文件不存在");
      }
     }
    
    
  ④捕获异常try catch
   捕获异常:
    Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式处理
    
   格式:
    try{
     // 编写可能出现异常的代码
    }catch(异常类型 e){
     处理异常的代码
     // 可以是记录日志、打印异常信息、继续抛出异常
    }
    
    try:该代码块中编写可能产生的异常代码
    catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理
    
   例子: 
        public static void main(String[] args) {
      try {
       read("a12.txt");
      }catch (FileNotFoundException e){
       // 打印异常
       e.printStackTrace();
      }
      System.out.println("over");
     }

     private static void read(String path) throws FileNotFoundException {
      if (!path.equals("a.txt")){
       throw new FileNotFoundException("文件不存在");
      }
       /* if (!path.equals("a.txt")){
       throw new IOException();
       }*/

     }
     
   捕获的异常常用的方法:
    Throwable类中定义了一些查看方法:

     - public String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。

     - public String toString():获取异常的类型和异常描述信息(不用)。
     - public void printStackTrace():打印异常的跟踪栈信息并输出到控制台。

      包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。

      在开发中呢也可以在catch将编译期异常转换成运行期异常处理。

     多个异常使用捕获又该如何处理呢?

      1. 多个异常分别处理。
      2. 多个异常一次捕获,多次处理。
      3. 多个异常一次捕获一次处理。

     一般我们是使用一次捕获多次处理方式,
     格式如下:
      try{
         编写可能会出现异常的代码
       }catch(异常类型A e){ 当try中出现A类型异常,就用该catch来捕获.
         处理异常的代码
         //记录日志/打印异常信息/继续抛出异常
       }catch(异常类型B e){ 当try中出现B类型异常,就用该catch来捕获.
         处理异常的代码
         //记录日志/打印异常信息/继续抛出异常
       }

     notes: 
      注意:这种异常处理方式,要求多个catch中的异常不能相同,
      并且若catch中的多个异常之间有子父类异常的关系,
      那么子类异常要求在上面的catch处理,
      父类异常在下面的catch处理
  ⑤finally代码块
   说明:
    有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。
    而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
    打开一些物理资源(比如磁盘文件/网络链接/数据库链接等)我们都得在使用完之后,最终关闭打开的资源
    
   用法:
    try catch finally:自身需要处理异常,最终还得关闭资源。
    
    notes: 
     finally不能单独使用。
     
   例子:
        public static void main(String[] args) {
      try {
       read("a11.txt");
      }catch (FileNotFoundException e){
       e.printStackTrace();
      }finally {
       System.out.println("不管怎么样我都要执行");
      }
      System.out.println("over");
     }

     private static void read(String path) throws FileNotFoundException {
      if (!path.equals("a.txt")){
       throw new FileNotFoundException("文件不存在!");
      }
     }
   tips:
    只有在try或者catch中调用退出JVM的相关方法时,此时finally才不会执行,否则finally用远会执行
     
     结果:
      不管怎么样我都要执行
      java.io.FileNotFoundException: 文件不存在!
      over
       at DemoThread.finallyTest01.read(finallyTest01.java:19)
       at DemoThread.finallyTest01.main(finallyTest01.java:8)
    
  ⑥异常注意事项
   ⑴运行时期异常被 抛出可以不处理,既不捕获也不声明抛出
   ⑵如果父类抛出多个异常,子类覆盖父类方法时,只能抛出相同的异常或者他的子集
   ⑶父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常,此时子类产生该异常,只能捕获处理,不能声明抛出
   ⑷当多异常处理时,捕获处理,前边的类不能时后边类的父类
   ⑸当try/catch后可以主机finally代码块,其中的代码一定会被执行,通常用于资源回收
   ⑹如果finally有return语句,永远返回finally中的结果,避免该情况
  

3.自定义异常

  说明: 
   为什么需要自定义异常类:

    Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是SUN没有定义好的,此时我们根据自己业务的异常情况来定义异常类。,例如年龄负数问题,考试成绩负数问题。

    在上述代码中,发现这些异常都是JDK内部定义好的,但是实际开发中也会出现很多异常,这些异常很可能在JDK中没有定义过,例如年龄负数问题,考试成绩负数问题.那么能不能自己定义异常呢?

    什么是自定义异常类:

    在开发中根据自己业务的异常情况来定义异常类.

    自定义一个业务逻辑异常: LoginException。一个登陆异常类。

   异常类如何定义:

    1. 自定义一个编译期异常: 自定义类 并继承于java.lang.Exception。
    2. 自定义一个运行时期的异常类:自定义类 并继承于java.lang.RuntimeException

  例子: 
   public class DiyETest {
    private static String[] names= {"bill","hill","jill"};
    public static void main(String[] args) {
     // 模拟登录
     try{
      // 可能出现异常的代码
      checkUsername("bill");
      // 如果没有就是注册成功
      System.out.println("注册成功");

     }catch (LoginException e){
      e.printStackTrace();
     }
    }

    private static boolean checkUsername(String uname) throws LoginException {
     for (String name:names){
      if (name.equals(uname)){
       // 如果名字在其中 则抛出 登录异常
       throw new LoginException("禁止登录");
      }
     }
     return true;

    }
   }
   
   class LoginException extends Exception{
    public LoginException() {
    }

    /**
     *
     * @param name 表示异常提示
     */
    public LoginException(String name){

     super(name);
    }
   }
  

5Java异常处理的更多相关文章

  1. 动手动脑5JAVA项目中的常用的异常处理情况

          Java异常处理的几个原则如下.     (1)不要丢弃异常,捕获异常后需要进行相关处理.如果用户觉得不能很好地处理该异常,就让它继续传播,传到别的地方去处理,或者把一个低级的异常转换成应 ...

  2. 关于.NET异常处理的思考

    年关将至,对于大部分程序员来说,马上就可以闲下来一段时间了,然而在这个闲暇的时间里,唯有争论哪门语言更好可以消磨时光,估计最近会有很多关于java与.net的博文出现,我表示要作为一个吃瓜群众,静静的 ...

  3. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  4. 异常处理汇总 ~ 修正果带着你的Net飞奔吧!

    经验库开源地址:https://github.com/dunitian/LoTDotNet 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983 ...

  5. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  6. IL异常处理

    异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...

  7. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  8. 【repost】JS中的异常处理方法分享

    我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...

  9. 札记:Java异常处理

    异常概述 程序在运行中总会面临一些"意外"情况,良好的代码需要对它们进行预防和处理.大致来说,这些意外情况分三类: 交互输入 用户以非预期的方式使用程序,比如非法输入,不正当的操作 ...

随机推荐

  1. C# 匿名类型var

    格式: var 名字=new {字段赋值}:c#中只是作为推断,根据赋值推断出类型,隐式类型 var. 隐式类型的本地变量是强类型变量(就好像您已经声明该类型一样),但由编译器确定类型. 1)var类 ...

  2. [HAOI2010]订货 BZOJ2424

    分析: 能看出来,这是一个费用流的题,建图很朴实,i连i+1,费用为存储费用,流量为仓库容量,之后S连i,费用为单价,流量为inf,之后i连T,流量为a[i],费用为0,之后裸上费用流... 附上代码 ...

  3. vi学习

    刚开始学习vi,所以,一步一步开始 先贴出一个相关的学习链接https://www.cnblogs.com/ranjiewen/p/5901181.html 这个学习链接里面的东西还是比较详细的,但是 ...

  4. 百度谷歌雅虎三大搜索引擎比较和如何配置谷歌访问助手访问Google搜索服务

    引言: 由于近期网上盛传”百度搜索引擎已死“的消息,引发个人对于搜索引擎的思考.百度作为最大的中文搜索引擎,确实有着很大声誉,再加上本地化的优势,正成为国人们的首选,但是作为一名技术开发人员,使用搜索 ...

  5. 20155227《网络对抗》Exp3 免杀原理与实践

    20155227<网络对抗>Exp3 免杀原理与实践 实践内容 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等 ...

  6. Health Endpoint Monitoring模式

    Health Endpoint Monitoring模式是一种用来监控服务健康状态的模式. Health Endpoint Monitoring模式通过在应用内额外暴露一个可以进行功能检查的接口来实现 ...

  7. ubuntu 12.04 桌面版关闭图形界面

    对于12.04的ubuntu桌面系统,如果想在开机的时候直接进入字符界面,那可以: 编辑文件 /etc/init/lightdm.conf,在第12行附近,原句“ and runlevel [!06] ...

  8. flask前端与后端之间传递的两种数据格式:json与FormData

    json格式 双向! 前端 ==>后端:json格式 后端 ==>前端:json格式 html <!-- html部分 --> <form enctype='applic ...

  9. HNOI2019 摸鱼记

    感觉准备省选时有点浮躁,没有准备联赛时那样认真, 希望能将这次省选当做一个教训吧QAQ. Day -inf 基本上把要学的东西都学了,至少做到了自己心里有底. Day 0 乒乓球室没开差评,打隔膜不带 ...

  10. 移动端页面滑动时候警告:Unable to preventDefault inside passive event listener due to target being treated as passive.

    移动端项目中,在滚动的时候,会报出以下提示: [Intervention] Unable to preventDefault inside passive event listener due to ...