------- android培训、java培训、期待与您交流! ----------
异常
异常就是程序在运行时出现不正常的情况。JAVA中所有的异常都从Throwable类中继承,分为两个部分:一部分是Error,另一部分是Exception。Error是指不可处理的异常。Exception指通过一些方法是可以将结果处理的错误。异常又分为运行时异常和非运行时异常。运行时异常是由于程序编写错误造成的。对于一个程序来说应该尽可能的想到在数据操作过程中的所有情况。对每一种情况都要有相应的处理方式。并且在程序编写完成以后要定期的对程序进行维护。
- 异常的概述:
- 异常的由来:
- 问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。其实就是java对 不正常情况进行描述后的对象体现。
- JAVA中Throwable是所有异常类的父类,它分为两类。
- 异常的体系:(不论Error还是Exception,都有它们的共性内容:不正常情况的信息、引发原因等)
- Error:严重的问题,一般不编写针对性的代码对其进行处理。出问题的地方根本不是程序编写的问题。
- Exception:非严重的问题,可以使用针对性的处理方式进行处理。
- 异常的分类:
- 编译异常:非RuntimeException异常以及其子类。
- 非编译异常:RuntimeException异常以及其子类
- 异常的由来:
- 异常的处理:
- JAVA中提供了特有的语句对异常进行处理.(try、catch、finally语句)
- try、catch语句组合。
- 格式:
try { 需要被检测的代码; } catch(异常类 变量) { 处理异常的代码;(处理方式) }
- 异常处理流程:在try中放入可能会出现异常的代码,如果代码出现异常首先在调用函数上抛出异常实体,然后在catch语句中如果有该异常的声明,则该异常被catch语句接收。接收以后就执行catch语句里面的内容,将该异常处理。
- 代码示例:
class Demo { int div(int a,int b) { return a/b; } } class ExceptionDemo { public static void main(String[] args) { Demo d = new Demo(); try { int x = d.div(4,0); System.out.println("x="+x); //因为x在try语句里面定义的一个局部变量 } //所以应该把操作x的语句都放在一起 catch (Exception e) { System.out.println("除数为负数");//定义异常的处理方式 } System.out.println("over"); } }
- 代码说明:首先程序现在内存中建立对象(Demo d),当d对象调用div函数的时候 ,就把4和0分别传给了Demo中div方法的a和b。然后a和b进行运算,因为在计算过程中产生了jvm识别的算术运算的问题。就在在returna/b,这句后抛出一个异常实体new AritchmeticException();抛给了调用它的调用者。在抛出异常后被try检测到异常,如果在catch语句里面声明了该类异常,于是把该异常抛给catch。此时代码转到catch定义的处理方式中去执行。执行完毕后,接着执行打印语句System.out.println("over"); 如果没有异常则不执行catch语句。
- 格式:
- try、catch、finally语句的组合:
- finally语句块中一般是用来释放资源的操作。
- 格式:
try { 需要被检测的代码; } catch(异常类 变量) { 处理异常的代码;(处理方式) } finally { 一定要执行的代码; }
- try、finally语句的组合:
- 用于异常不在本方法中执行,但是一定的关闭资源。
- 格式:
try { 需要被检测的代码; } finally { 一定要执行的代码; }
- 在Throwable中定义的一些常见方法:
- String getMessage():返回异常的详细消息。
- void printStackTracr:打印异常在堆栈中的跟踪信息。包括(异常名称、异常信息、异常位置)。为jvm默认的异常处理方式。
- try、catch语句组合。
- 将异常抛出:(所调用方法上声明有异常抛出,可以使用抛出异常也可以使用try,catch处理)
- 处理异常的格式:
代码说明:流程和上面一样,只是在这个程序中,不用进行代码检测,如果有异常抛出,就直接在主函数上抛出,抛给了虚拟机,jvm采用默认的异常处理机制。打印class Demo { int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。 { return a/b; } } class ExceptionDemo { public static void main(String[] args) throw Exception //将可能产生的异常声明抛出(抛给了jvm) { Demo d = new Demo(); int x = d.div(4,1); System.out.println("x="+x); System.out.println("over"); } }
- JAVA中提供了特有的语句对异常进行处理.(try、catch、finally语句)
- 异常的声明:
- 在功能上通过throws关键字声明该功能有可能会出现问题。
- 在功能上声明抛出异常后,在调用该功能时就必须进行处理(捕捉或者抛出)。
- 多异常的处理:
- 声明异常时,建议声明更为具体的异常,这样处理更加具有针对性。
- 在处理异常时,抛出什么异常就处理什么异常。不能笼统的用catch(Exception e)将所有的一种都调用一种处理方式,抛出几个异常就处理几个异常。使之对异常的处理更具针对性。不要定义更多的catch处理方式。在语法上面就是抛出几个异常就用几个catch块进行处理。
- 对异常的处理方式应该不是简单的调用打印信息,应该将其记录,让程序员定时的去常看异常日志,进行程序的相关维护。
- 当出现了我们定义之外的异常,应该让程序停掉,让程序员修正程序使之有更针对性的处理。
- 声明异常时,建议声明更为具体的异常,这样处理更加具有针对性。
- 自定义异常:
- 自定义异常的原因:因为在实际项目中会出现特有的问题,而这些问题并未被JAVA所描述封装对象。对于这些特有的问题可以按照java的对问题封装的思想进行自定义的封装。
- 如何进行自定义异常的封装:
- 继承Exception或RuntimeException
- 继承Exception:表示该异常可以是操作的问题可以被修正。
- 继承RuntimeException:不允许发生的事情。
- Excetpion中原有方法的使用:
- 在Exception中有Exception(),Exceptoin(String message),Exceptoin(String message,Throwable cause)等构造函数。其中String message表示异常的详细信息,Throwable cause表示新的异常。所以在我们需要使用这些参数的时候可以直接继承父类的方法不需要自己定义。在我们打印该异常的时候,jvm就会自动调用getMessage()方法获取该异常的详细信息。
- 自定义异常的封装:
- 将异常定义成一个类,根据异常的种类选择继承Exception或者RuntimeException.
- 在自定义异常类中定义异常类的主体,如果在父类中已经定义,则通过super调用就可以了。
- 在使用上,则在异常发生的位置手动抛出该异常实体。并且在函数上声明(RuntimeException的子类则不用声明)。其他的和JAVA已经封装的异常一样。
- throw和throws的区别:
- throw用在函数内,抛出的是异常实体,只能抛出一个实体。
- throws用来在函数上声明抛出的异常类,可以声明多个异常类。
- 自定义异常代码示例:
class FuShuException extends Exception //如果继承的是RuntimeException则在下面程序中使用的时候不用处理 { private int value; //自定义异常中的特有数据 FuShuException() //构造函数,函数体在Exception中已定义,直接通过super调用 { super(); } FuShuException(String msg) { super(msg); } FuShuException(String msg,int value) { super(msg); this.value = value; } public int getValue() //操作自定义异常的特有数据,Exception中未定义 { return value; } } class Demo { int div(int a,int b)throws FuShuException//RuntimeException则可以不用在函数上声明。 { if(b<0) //手动通过throw关键字抛出一个自定义异常对象。 throw new FuShuException("出现了除数是负数的情况------ / by fushu",b); return a/b; } } class ExceptionDemo3 { public static void main(String[] args) { Demo d = new Demo(); try //在使用时对异常的处理,如果是RuntimeException则不用处理 { int x = d.div(4,-3); System.out.println("x="+x); } catch (FuShuException e) { System.out.println(e);//会自动调用toString()方法,打印异常的详细信息 } System.out.println("over"); } }
- 继承Exception或RuntimeException
- 异常覆盖的特点:(多态)
- 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
- 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
- 如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
- 在开发中的建议:
- 最好将异常的处理代码和正常处理相分离。即如果出现非法操作,程序应该采取异常处理,程序结束。
- 在处理异常的时候要定义具有针对性的处理方式,不能在catch语句里面什么都不写。
- 如果真的发生异常,应该保存在程序日志里面。