黑马程序员_面向对象(异常)

来源:互联网 发布:淘宝爱互动 编辑:程序博客网 时间:2024/06/06 09:41

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 

面向对象(异常)

一、异常概述

异常就是不正常的对立面,在程序里一般变现为出错或一些语句的提醒,比如数学里我们要除以一个数,如果这个数是零的话,那么系统就会报错:

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

这时系通就提醒你,算数方法出错了,下面会告诉你具体什么位置,哪个元素等等。同时,哪个语句下面的语句就不会运行,就是说系统报出异常,程序就会停止。

从上面看来,异常:就是程序运行时出现的不正常情况。

异常的由来:问题也是现实生活中的一个具体的事物,也可以通过java类的形式,进行描述并封装对象,其实就是java对不正常情况描述后的对象体现。

Java中对于问题的划分分为两种:1、严重问题。2、非严重问题。对于严重的问题,java通过Error来描述,对于非严重的,java通过Exception进行描述。对于Error类来说,在java中是不可处理的,比如,我运行一个程序,但是这程序的类根本就没有,那么这种就是错误。Exception表达出来的错误,是可修复的。两者也有一些共性内容,想不正常情况,都会报出错误信息。

注意,既然两者有个共性,那么就会有他们的父类,这样就形成了基本的体系。这个父类时Throwable。它包含两个子类:1Error  2Exception

 

 

既然是异常,所以我们重点看到异常,Exception

 

二、异常处理

1try-catch语句处理

既然系统会抛出异常信息,那么我们就可以处理这些异常信息的。Java中提供了处理异常的方法,就是try-catch语句。格式如下:

try{

        被检测语句;

}

catch(异常类名字){

        处理异常语句;

}

finally{

        一定执行语句;

}

 

这个格式是固定的,里面具体执行语句,这里再说一下。

try语句中执行的语句,是我们要检测的代码,比如刚才举得例子,出发中,除数为0,我们就把这个语句放入try这个语句块中。

catch中处理的上面被检测语句尝试的异常,里面加我们要处理的方式,要注意,语句中会传入一个异常类,这个类是Exception类或其子类。

finally的语句是一个不管程序是否报出异常,都会执行块,里面的代码一定会执行。

这样,对具体的执行流程,我们通过一个程序来看:

 

class ExceptionDemo

{

         try

         {

                   intx = 4/0;

                   System.out.println(x);

         }

         catch(Exception e )

         {

                   System.out.println("wrong");

         }

}

看上面程序,

1)     程序运行出现错误:

如果没有try-catch语句,那么当除数为0的时候,系统就会检测到这一错误,所以系统就会把这一错误装成一个对象,交给系统去处理,所以当程序运行出错时,系统就会抓到这一对象,去处理,报异常,错误语句后面的语句就不会执行了。如果有try-catch语句,就不一样了,首先错误语句会产生一个异常类的对象,系统检测到你有异常处理语句,所以catch就“抓”到了这一异常类的对象,把这个对象传入到catch语句中,执行我们自己定义的处理方式,因为系统错误处理了,所以程序就会在catch之后继续执行,但本身错误语句后面的语句就不会执行了,如例子中的System.out.println(x)语句就不会执行。

2)     程序运行没有错误:

没有try-catch语句的话,会正常运行。有try-catch语句,则不会执行catch里面对异常处理的语句。

除了我们自定义处理方式,我们可以再catch块中,对e进行操作,就是对异常类对象进行操作。常用方法有:getMessage():获取异常信息, toString():返回此异常的简短描述,printStackTrace():打印出异常信息和异常出现位置。

其实,jvm默认异常处理机制,就是调用printStackTrace()方法,打印异常的堆栈的跟踪信息。

 

2、抛出异常

   对于抛出异常的理解,是这样的。我们在使用一个功能的时候(比如说某一个函数),就这个功能在使用的时候可能会出错,我们的一个处理方式,就是上面的try-catch语句,但从功能设计者的角度来讲,我想要告诉你这个功能运行时可能会出现问题,这时的方法就是在我功能的方法上,我声明这个方法会出现异常,从使用者角度来讲,对你说的这个异常,我不想进行try-catch处理,那么我也把这异常声明出来,抛给下一个调用者,当然了就是JVM了,有JVM自己去处理。这里用到抛出异常的关键字:throws

        抛出异常的格式为:throws Exception       可以声明多个异常,用逗号隔开

当然了,抛出异常,可以是Exception,但这个范围太大了,一般抛出的异常都是程序里功能相关的,比如算数异常,IO异常等等。而且,一般我们都不抛异常,我们还是以try-catch处理异常为主。

 

3、多异常处理情况

首先声明异常时,要声明更为具体的异常,这样处理的可以更具体。这样,我们就可以对相对应的异常,做出更精准详细的处理方式。

处理的时候,就要有相对应的处理,示例程序如下:

class ExceptionDemo{

         try{

                   intx = 4/0;

                   System.out.println(x);

         }

         catch (ArrayIndexOutOfBoundsException e)

                   System.out.println("wrong");

         }

         catch (IOException e )

                   System.out.println("wrong2");

         }

}             

其次,对方声明及格异常,就对应接catch块(如上面示例),不要定义多余的catch块,如果多个catch块中出现的异常继承关系,父类异常的catch块放在最下面。

对于异常的处理,有几个异常,就用几个catch块进行相对应的异常处理,但注意一点,catch抓住的是Exception异常,这样处理并不具体,而且我们在处理时候不知道到底什么情况的异常。而且,这种catch块不能放在第一catch块的位置,否则,就只会执行第一个catch块,后面两个永远也执行不到。所以,对于异常的处理,要坐到对应处理,不要一刀切。示例程序如下:

         try{

                   intx = 4/0;

                   System.out.println(x);

         }

         catch( ArrayIndexOutOfBoundsException  e )

                   System.out.println("wrong");

         }

         catch( Exception e )

                   System.out.println("wrong2");

         }

看程序中的两个catch,两者有继承关系,所以作为父类的Exception块,就放到所有catch块的最后。

最后,建立catch处理时,在catch块中要定义具体的处理方式,不要简单定义一句话,也不要简单书写以个输出语句。

通常,做程序的时候,会把异常记录在某一文件了里,就是异常日子。

 

三、自定义异常

自定义异常,就是我们自己在写程序或者做项目的时候,会有一些项目中特有的问题,这些问题java中没有对应的对象,所以对于这些特有问题可以按照java面向对象的思想,将特有问题进行封装,那么我们就该自己定义异常,封装对象,以供声明或抛出。

这里的定义的方法:

1、  我们要建立自己的异常身声明,要把我们建立的体系方法java中的异常体系中。那么就要继承Exception类。

2、  Java中,如果程序产生异常,那么java就会自动把异常封装成对象进而抛出。而我们自己定义的异常,java不认识,所以我们要自己建立对象进行抛出。这里就用到关键字:throw(注意,和throws有区别的),后面接自定义异常对象。格式为:

           throw   new   自定义异常类的类名();

3、  如果函数内部throw抛出异常对象,那么就必须要给对应的处理动作,要么进行try-catch处理,要么在函数上声明让调用这处理。一般情况,在函数内出现异常,函数上需要声明。

4、  如何自定义异常信息?因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息通过super传递给父类,那么就可以直接通过getMessage方法获取自定义异常信息。

示例程序:

classFushuException extends Exception{

FushuException(String message){

           super(message);

}

}

class TestDemo    {

int div(int a,int b)  throws FushuException {

           if(b<0)

                    throw FushuException("负数");

           return a/b;

}

}

 

 

总结:

1)  异常,java中就是程序运行时产生的错误。

2)  异常Exception,错误Error,都是Throwable的子类

3)  异常处理有两种方法:一是try-catch语句,二是函数上声明异常。当函数抛出异常时,使用throws关键字,多个异常,以逗号隔开。进行try-catch语句处理时,有几个异常就有几个catch块。

4)  注意try-catch处理异常时,如果catch块中有异常关系,那么catch中父类的放在多个catch块的最后。

5)  catch块中的处理方式,不要是简单的输出语句,最好是详尽只管的处理语句。

6)  一旦有异常,就意味着程序的停止

7) 自定义异常注意:一、要继承Exception或其父类,要把自己定义异常纳入java异常体系,这样才可以使用。二、函数内部,抛出自定义异常类的对象,用关键字throw(当然也可以直接抛java自己有的异常类对象),这时必须在函数上声明异常。

8)  自定义异常:因为继承Exception,可以直接引用父类方法和构造函数,是自定义异常程序简单化。

9)  注意,有throw语句时,下面不要跟任何语句,执行不到,否则编译失败。

 

throwthrows的区别

1、位置区别   throw使用在函数内;throws使用在函数上

2、使用方法区别  throw后面接异常类的对象;throw后面接异常类,可以有多个,用逗号隔开

 

 

四、特殊异常类RuntimeException

Exception中特殊异常子类RuntimeException,运行时异常。关于这个异常有两点:

一、如果再函数内抛出该该异常,函数上可以不用声明,编译一样通过。

二、如果再函数上声明了该异常,调用者可以不用进行处理,编译一样通过。

 

之所以不用函数上进行异常声明,是因为不需要让调用者处理。当该异常发生时,希望程序停止,因为运行时,出现了无法继续运算的情况,希望停止程序,对代码进行修正。

依照上述,那么我们在自定义异常时,如果该异常方法,无法继续运算,就让自定义异常继承RuntimeException

 

总结来说:

1)  RuntimeException,函数内抛出,函数上可以不声明异常。函数上抛出异常,调用者不用处理

2)  异常就分为:一、编译时异常Exception  二、运行时异常RuntimeException

3)  自定义异常,可以根据需要,继承的异常类可以分为:一、继承Exception,二、继承RuntimeExce

 

 

五、finally语句

在上面的异常概述里,finally语句中是一定会被执行的语句。

小知识,return可以结束主函数运行。

因为finally中的语句一定会被执行,所以通常用于关闭资源

注意这种格式是成立的:

try{

}

finally{

}

 

六、覆盖时异常特点

1、子类在覆盖父类时,如果父类方法抛出异常,那么子类的覆盖该方法,只能抛出父类异常或该异常类的子类。

2、如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集

3、如果,子类覆盖父类,其他方法抛出的是除了父类异常和它的子类异常外,只能在函数内部进行try-catch处理,不能抛出异常声明。

4、如果父类或接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出

        如果子类方法发生了异常,就必须要进行try-catch处理,绝对不能抛。

 

0 0
原创粉丝点击