------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一异常由来:
问题也是现实生活中一个具体的事物,也可以通过Java的类的形式进行描述。并封装成对象。 其实就是Java对不正常情况进行描述后的对象体现。描述不正常的情况的类,就称为异常类。 不同的问题用不同的类进行具体的描述。比如角标越界异常,空指针异常等等。问题很多,意味着描述的类也很多,将其共性进行向上抽取,形成了异常体系。二异常的好处:
1将问题进行封装。2将正常流程代码和问题处理代码相分离,方便于阅读。
三异常体系的特点:
子类的后缀名都是用父类名作为后缀,阅读性很强。 Throwable: 无论是Error,还是Exception。 问题,问题发生就应该可以抛出,让调用者知道并处理。 该体系的特点就在于Throwable及其所有的子类都具有可抛性。 可抛性到底指的是什么呢?throws throw 怎么体现可抛性呢?凡是可以被这两个关键字所操作的类和对象都具备可抛性。1, 一般不可处理的。Error
特点:是同Jvm抛出的严重性的问题。 通常出现重大问题如:运行的类不在在或者内存溢出等。这种问题发生一般不针对性处理。直接修改程序。 错误:通常是不编写代码对其进行针对处理。
2,可以处理的。Exception 处理Exception异常有俩种方法:
一是:在运行时运行出现的一些情况,可以通过 try catch finally
二是:通过throws在函数上声明。(如果函数内throw异常,那么函数就必须声明)
异常:是在运行时期发生的不正常情况..
四处理异常(Exception)的几种格式:
格式一:try{
可能发生异常的代码;
}
catch(接收捕获异常类的对象 异常类引用变量){
处理代码;
}
格式二:
try{
可能发生异常的代码;
}
fianlly{
一定要执行的语句;(通常用于关闭资源)
}
格式三:
try{
可能发生异常的代码;
}
catch(捕获异常类的对象 异常类引用变量){
处理代码;
}
finally{
一定要执行的语句;(通常用于关闭资源)
}
四举例:除数为零的异常
<span style="font-family:SimSun;font-size:14px;">class Object1
{
public static void main(String[] args)
{
Demo d=new Demo();
try
{
int z=d.getNum(4,0);
System.out.println(z);
}
catch (ArithmeticException e)
{
System.out.println("除零了");
}
}
}
class Demo
{
public int getNum(int x,int y)
{
return x/y;
}
}
</span>
五throw和throws的用法
(1)、throw定义在函数内,用于抛出异常对象。(2)、throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开
异常的选用:
当抛出的异常是调用者误操作完成的,那么继承RuntimeException类,如果该异常的发生,就让该程序停掉。
一般情况下继承的都是Exception异常。
异常有两种:
编译时异常:
该异常在编译时,没有处理(没有抛出也没有try),编译失败 运行是异常(编译时不检测):
在编译时,不需要处理,编译器不检查 该异常的发生,建议不处理,让程序停止,需要对代码进行修正
注意:
当函数内有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败
Exception有一个特殊的子类,RuntiimeException。
也就是说,函数内如果抛出的RuntimeException异常,函数上可以不用声明。
注意: 如果Exception在内部被解决,比如内部catch(捕获)并对异常进行了处理,则该方法不用声明异常。 记住一点,catch是用于处理异常,如果没有catch就代表异常没有被处理。 如果该异常是检测,可以没有catch语句。 当然:如果抛出的是多个异常,就要有几个catch,也有简单的做法,直接抛父类异常Exception
六异常处理的原则:
1,函数内容如果抛出需要检测的异常,那么函数上必须要声明。 否则必须在函数内用try catch捕捉,否则编译失败。2,如果调用到了声明异常的函数,要么try catch要么throws,否则编译失败。 如果调用的函数抛出异常,那么调用者可以try catch也可以throws 如果调用的是复写父类的函数抛出异常,那么调用者只能抛出父类同样的异常,或者父类异常的子集
3,什么时候catch,什么时候throws 呢?
功能内容可以解决,用catch。 解决不了,用throws把异常告诉调用者,由调用者解决 。
4,一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。 内部有几个需要检测的异常,就抛几个异常,抛出几个,就对应有几个catch。
5,抛到最后抛给谁才是个头呢?答案是抛到虚拟机才是头。
fianlly 特殊之处:
finally语句中定义的是一定要执行的语句,通常用于关闭资源。(因为资源必须释放) finally除非遇到System.exit(0);也是就虚拟机退出才不会执行。
七子类覆盖父类时对异常处理的注意事项:
1、如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。2、如果父类方法抛出多个异常,那么子类再覆盖该方法时,只能抛出父类异常的子集。也就是父类如果抛多个异常,那么我们不能直接抛Exception异常。 如果抛一个异常的时候,是可以抛父类异常的
3、如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
4、如果子类方发发生了异常,就必须要进行try处理,绝对不能抛。
5、如果在子类的覆盖方法确实需要抛出非父类的异常或者该异常的子类,则必须在内部解决。
八自定义异常
定义类继承Exception或者RuntimeException 。其实我们这样也是用面向对象思考问题,把我们程序设计中可能出现的问题进行了封装(1)、为了让该自定义类具备可抛性
(2)、让该类具备操作异常的共性方法
(3)、当要自定义异常的信息时,可以使用父类已经定义好的功能,异常信息传递给父类的构造函数。
<span style="font-family:SimSun;font-size:14px;">class FushuException extends Exception
{
FushuException(String message)
{
thi.message=message;
}
}</span>
九举例:自定义异常。把除数为负数自定义为异常
<span style="font-family:SimSun;font-size:14px;">class Object1
{
public static void main(String[] args)
{
Demo d=new Demo();
try
{
int z=d.getNum(4,0);
System.out.println(z);
}
catch (FuShuException ex)
{
System.out.println(ex.getMessage());
}
catch (ArithmeticException e)
{
System.out.println("除零了");
}
}
}
class Demo
{
public int getNum(int x,int y)throws FuShuException
{
if(y<0)
{
throw new FuShuException("出现负数了");
}
return x/y;
}
}
class FuShuException extends Exception
{
FuShuException(String message)
{
this.message=message;
}
}
</span>
10练习:
毕老师用电脑上课。 问题领域中涉及两个对象。 毕老师,电脑。
分析其中的问题。 比如电脑蓝屏啦。冒烟啦。
<span style="font-family:SimSun;font-size:14px;">class Object1
{
public static void main(String[] args)
{
Teachet t=new Teacher("zhangsan");
try
{
t.useComputer();
}
catch (NoPlanException ec)
{
System.out.println(ec.getMessage());
}
}
}
//自定义异常
class LanPingException extends Exception
{
LanPingException(String message)
{
this.message=message;
}
}
//自定义异常
class MaoYanException extends Exception
{
MaoYanException(String message)
{
this.message=message;
}
}
//自定义异常
class NoPlanException extends Exception
{
NoPlanException(String message)
{
this.message=message;
}
}
/*对电脑进行描述
一个是电脑的运行方法
一个是电脑的重启方法
*/
class Computer
{
private int state=1;
public void comRun() throws LanPingException, MaoYanException
{
//电脑状态判断
if(state==2)
{
throw new LanPingException("电脑蓝屏了");
}
//电脑状态判断
if(state==3)
{
throw new MaoYanException("电脑冒烟");
}
}
public void changeState()
{
state=1;
}
}
/*对教师进行描述
教师属性 姓名(name),电脑(comp)
教师行为 讲课 如果出现异常,教师还可以布置练习方法
*/
class Teacher
{
private Computer c;
private String name;
Teacher(String name)
{
this.name=name;
c=new Computer();
}
public void useComputer() throws NoPlanException
{
try
{
c.comRun();
}
catch (LanPingException e)
{
System.out.println(e.getMessage());
c.changeState();
}
catch (MaoYanException ex)
{
ziXi();
System.out.println(ex.getMessage());
throw new NoPlanException("不能正常上课了");
}
}
public void ziXi()
{
System.out.println("自习");
}
}
</span>
11练习:
有一个圆形和长方形, 都可以获取面积,对于面积如果出现非法的数值,视为是获取面积出现问题 问题通过异常通过异常来表示现有对这个程序进行基本设
于面向对象的分析,分析出对圆和长方形求出对应的面积。 由于都是求面积,所以把它们的共性向上抽取,抽成一个接口; 方便让程序员们一看就知道这个体系是在求面积。
<span style="font-family:SimSun;font-size:14px;">class Object1
{
public static void main(String[] args)
{
func(new Rec(0,3));
func(new Circle(0));
}
public static void func(Shape s)
{
s.getArea();
}
}
class NoValueException1 extends RuntimeException
{
NoValueException (String message)
{
super(message);
}
}
class NoValueException2 extends RuntimeException
{
NoValueException (String message)
{
super(message);
}
}
interface Shape
{
public void getArea();
}
class Rec implements Shape
{
private int len,wid;
Rec(int len,int wid)
{
if(len<=0 ||wid<=0)
{
throw new NoValueException1("出现非法值");
}
this.len=len;
this.wid=wid;
}
public void getArea()
{
System.out.println(wid*len);
}
}
class Circle implements Shape
{
private double d;
private final double X=3.14;
Circle(double d)
{
if(d<=0)
{
throw new NoValueException2("半径圆了出现非法值");
}
this.d=d;
}
public void getArea()
{
System.out.println(X*d*d);
}
}
</span>