黑马程序员_面向对象(异常)
2014-10-18 12:26
176 查看
------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。它包含两个子类:1、Error 2、Exception
既然是异常,所以我们重点看到异常,Exception
二、异常处理
1、try-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语句时,下面不要跟任何语句,执行不到,否则编译失败。
throw和throws的区别:
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处理,绝对不能抛。
相关文章推荐
- 黑马程序员__java基础__面向对象(多态、异常)
- 黑马程序员------面向对象(No.7)(内部类、异常概述、异常try-catch、异常声明throws、多异常处理)
- 黑马程序员——面向对象--异常
- 黑马程序员——面向对象之异常(一)
- 黑马程序员——Java 面向对象_异常
- 黑马程序员---------Java面向对象——异常总结
- 黑马程序员------面向对象(No.8)(自定义异常、throw(throws)、RuntimeException、覆盖时异常、异常总结)
- 黑马程序员——面向对象(异常-上)
- 黑马程序员_Java基础_面向对象(内部类、异常1)
- 黑马程序员_JAVA笔记09—面向对象5(内部类、异常)
- 黑马程序员——面向对象之异常(二)
- 黑马程序员——【Java基础】——面向对象(二)异常机制、包(Package)
- 黑马程序员_JAVA笔记10——面向对象6(异常、包)
- 黑马程序员Java面向对象——异常
- 黑马程序员——面向对象(三)(多态和异常简述)
- 黑马程序员 Java面向对象——异常
- 黑马程序员_面向对象3_(异常Exception、包package、String类、StringBuffer类)
- 黑马程序员——java面向对象(异常篇)
- 黑马程序员 java 基础 毕向东 面向对象 异常 以及 package 的使用
- 黑马程序员_java_面向对象_异常处理