异常11

来源:互联网 发布:斗牛牛软件下载 编辑:程序博客网 时间:2024/05/20 16:12

异常

异常:就是程序 运行  时出现的不正常情况。

 

发现,当调用者往里传入了除数0,就发生。编译通过(语法没错误),而运行失败的情况。

出现一个ArithmeticException/ by zero 一个异常。

 

运行提前终止,后续的代码就不会在执行了。

 

 

 

其实异常就是程序中出现的问题:这个问题包括问题的名称,问题的信息,以及问题出现的位置。

这个问题中内部中的有很多,按照面向对象将这个问题封装成了对象。

 

通过if判断形式,也可以对问题进行处理。

但是这样会导致,问题处理代码和正常的业务流程代码都定义在了一起,不便于阅读,

当把问题封装成对象后,当该问题产生后,可以让程序进行跳转有一个特定的区域对问题进行处理。

这样,异常的出现可以时问题处理代码和业务逻辑代码相分离,提高了程序的阅读性。

 

 

Java对常见的一系列都进行了描述,并进行了对象的封装。

 

查阅一下API。发现异常中很多子类。

因为常见问题很多,就对这些问题进行描述并建立了体系。

 

问题分为两大类:

1,可以处理的问题。

一般用Exception(异常)来进行描述。这个问题可以有针对性的代码进行处理。

2,重大错误问题,

Error进行描述。这个问题发生后,一般不编写针对的代码进行处理,而是要对程序进行修正。

通常都有JVM抛出的问题。

 

这两个派系,他们的子类都有一个共同特征:

所有子类名成结尾都是以父类名作为后缀。

 

问题:就如同疾病:

可以治愈的疾病。Exception

也有绝症。Error.

 

 

无论错误,异常,他们都有,名称标识,同时也有问题的信息。问题出现的位置。

 

既然有这样的共性可以向上继续抽取。

他们就有了一个共同的父类Throwable,该父类中就定义了该体系中最共性的方法.

 

String getMessage():获取异常的信息。

String toString():将异常对象变成字符串。其实该类是覆盖Object类中的toString();

void printStackTrace():打印异常在内存中的详细信息。直接打印到控制台。

 

 

异常的处理。

 

 

有两种:

1,抛出。

2,使用java中指定的代码块进行自定义处理。

try

{

需要检测异常的代码;

}

catch(异常类 变量)

{

异常处理代码;

}

finally

{

一定会被执行的代码;

}

 

调用了div功能,该功能并未声明有任何问题,所以调用者是不需要进行针对处理。

 

但是这样程序会有安全隐患。

所以在定义div功能时,就需要将容易发生的问题,明确出来,这样才方便于调用者进行处理

 

怎么明确呢?

可以在功能上通过throws关键字将问题的名称标识出来,让调用者可以知道.

 

 

处理异常:

要么throws,要么try

 

到底是try好呢?还是throws好呢?

 

原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这时用throws

 

 

如果使用到了一个声明了异常的功能时,

必须要对应的throws或者try的处理方式。否则编译失败。 

 

但是有一种特殊情况。

当功能上声明的异常是一个特殊的异常子类时,这时该功能被调用,可以不用任何处理方式,一样可以编译通过。

这个特殊异常就是Exception中的一个子类RuntimeException(运行时异常)

 

 

异常分两种:

1,编译时被检测的异常.包括除了Exception子类RuntimeException以外的所有异常。

如果在函数上声明,如果调用时,没有处理方式,编译会编译。

而且这种异常需要有针对性的处理方式。是可被处理的。

 

2,编译时不被检测的异常:包括RuntimeException以及子类。

该异常也称为运行时异常,如果功能声明了此异常,

调用者可以不用任何处理方式。通过该异常不需声明。 

如果发生,就是需要程序停止,对代码进行修正。

在自定义项目中,也会有很多问题发生,这些问题,有可能是项目特有问题,

是没有被java所描述的。

那么这时,就需要我们继续按照java的异常思想,将特有问题也封装成对象。

 

 

自定义异常。

将特有的问题进行描述,并封装成对象 。

 

 

//在下面示例中,要求,除数不可以为负数。

 

这种问题java没有提供先有的描述方式。

所以只有自己进行描述。

 

自定义异常的步骤:

定义一个类对问题描述。要想成为异常,必须继承异常类才可以。这样才可以成为异常体系中的一员。

 

其实最根本原因:异常体系和其他对象的不同之处在于异常体系都具备可抛性。

异常的类和对象都可以被两个关键字所操作,而且只有异常体系具备这个特点 

哪两个关键字呢?throws  throw

当函数内容通过throw抛出了一个编译时检测的异常。必须要有处理方式。

要么try,要么throws

 

 

处理调用出现异常的函数的原则:

调用了声明异常的函数,处理时,对方声明什么异常,我们就处理什么异常。

 

 

自定义异常可以继承Exception

也可以继承RuntimeException

如果该问题发生,不需要声明需要是调用修正代码,那么就需要继承RuntimeException

 

 

 

throwsthrow的区别:

throws用在函数上,用于声明该功能容易出现问题。可以调用者进行处理的。

throw用在函数内,用于抛出指定的具体异常对象。

 

throws后面跟的是异常类。可以跟多个,中间用逗号隔开。

throw后面跟的是异常对象。

 

 

只有异常体系的类和对象才可以被这两个关键字所操作。

 

 

 

Finally

finally代码块。

 

 

finally代码块中定义是用于关闭资源的代码。

 

举例:

 

操作数据库。

无论数据是否添加成功,都需要进行数据库的关闭动作,因为关闭动作可以释放数据库的资源。提高数据库的性能。

 

void add()

{

try

{

连接数据库。

 

添加数据。

 

}

catch(SQLException e)

{

异常处理方式。

}

finally

{

关闭数据库

}

 

 

}

 

 

 

 

try catch finally在使用的时候,

try可以和catch相结合使用,可以对应多个catch

 

如果没有catchtry可以和finally结合使用。

如果功能中,出现了编译时需要被检测的异常,如果没有被catch,就必须要throws声明,否则编译失败 

 

记住:只有catch是处理异常的代码块.

 

void show()throws Excpetion

{

try

{

code();//使用了底层资源。

throw new Excpetion();

}

finally

{

资源释放。

}

}

 

异常的处理细节:

 

1,当子类覆盖父类时,如果父类的方法抛出了异常,

那么子类覆盖父类要么不抛异常,要么抛出该异常或者该异常的子类。

2,如果父类抛出了多个异常,子类覆盖父类时,只能抛出这些异常子集。

 

简单一句话:子类只能抛父类的异常或者异常的子类或子集。子类不可以抛出父类没有的异常。

 

注意:如果被覆盖的方法没有异常抛出,那么子类的方法绝对不可以抛出异常。

如果子类方法内还有异常发生。那么子类只能try,不能throws.

 

面试细节:

try对应多个catch时,如果catch的类型有继承关系,那么父类型的catch一定要放在下面.

class BException extends Exception

BException(String msg)

{

super(msg);

}

}

class CException extends BException

{

CException(String msg)

{

super(msg);

}

}

 

class Fu

{

void show()throws Exception,BException,CException

{

System.out.println("123");

}

}

 

class  Exception2

{

public static void main(String[] args) 

{

try 

{

new Fu().show();

}

        catch(CException e)

{

System.out.println("e");

}

catch(BException e)

{

System.out.println("c");

}

catch(Exception e)

{

System.out.println("a");

}

}

}

 

 

void method()

{

 

throw new RuntimeException();

System.out.println("haha");//永远执行不到。是一句标准的废话。

 

}



原创粉丝点击