------- android培训、java培训、期待与您交流! ----------
异常
1.程序在运行时出现的不正常情况
不正常的情况有两种:
严重的:java通过Error类进行描述
对于Error一般不编写针对性的代码对其进行处理
不严重的:java通过Exception类进行描述
对于Exception可以使用针对性的处理方式进行处理
无论Error或者Exception都具有一些共性内容,即Throwable
2.异常的处理
处理语句
try
{
需要被检测的代码
}
catch(异常类 变量)
{
处理异常的代码,即处理方式
}
finally
{
一定会执行的语句
}
eg:
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);
}catch(Exception e){//Exception e = new ArithmeticException();
System.out.println("除零啦");
System.out.println(e.getMessage());// /by zero
System.out.println(e.toString());// 异常名称:异常信息
e.printStackTrace();// 异常名称,异常信息,异常出现的位置
}
System.out.println("over");
}
}
结果:
除零啦
/ by zero
java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at Demo.div(ExceptionDemo.java:4)
at ExceptionDemo.main(ExceptionDemo.java:13)
over
如果不做异常处理,int x = d.div(4,0);出现异常,
直接丢给虚拟机处理,虚拟机异常处理机制默认处理,程序出错,停止
jvm默认的异常处理机制,就是在调用printStackTrace,打印异常在堆栈的跟踪信息
3.上面那个例子中,存在一个问题
调用Demo类时,可能不知道里面具体的内容,调用的时候不确定需不需要抛异常,所以在定义Demo时,方法div需要throws关键字声明,提示需要捕捉或者抛出异常
class Demo{
int div(int a, int b) throws Exception{
return a/b;
}
}
主函数中两种处理方式,一种捕捉异常,如上面例子,另一种抛异常,如下:
class ExceptionDemo {
public static void main(String[] args) throws Exception{
Demo d = new Demo();
int x = d.div(4,0);
System.out.println("x="+x);
System.out.println("over");
}
}
4.对多异常的处理
1).声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2).对方声明几个异常,就对应有几个catch块,不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面
eg.
class Demo{
int div(int a, int b) throws ArithmeticException, ArrayIndexOutBoundsException{
int[] arr = new int[a];
System.out.println(arr[4];);
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);
}catch(ArithmeticException e){
System.out.println(e.toString());// 异常名称:异常信息
System.out.println("除零啦");
}catch(ArrayIndexOutBoundsException e){
System.out.println(e.toString());// 异常名称:异常信息
System.out.println("角标越界啦");
}
System.out.println("over");
}
}
5.建议在进行catch处理时,catch中一定要定义具体的处理方式
不要简单定义一句话,e.printStackTrace(),也不要简单就书写一条输出语句
比较常见的处理方式:文件记录问题,生成异常日志文件
6.自定义异常,项目中可能会出现特有的异常,而这些问题并未被java所描述并且封装对象,所以对于这些额特有的问题可以按照java的对问题封装的思想将特有的问题,进行自定义异常封装
如上面那个例子,当除数是0的时候错误,同时除数小于0的时候也是错误的,那么做如下定义:
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作
要么在内部try..catch处理
要么在函数上声明让调用者处理
如何定义异常信息?
因为父类中已经把异常信息的操作都完成了,
所以子类只要在构造时,将异常信息传递给父类通过super语句,
那么就可以直接通过getMessage方法获取自定义的异常信息
class FuShuException extends Exception{
FuShuException(String msg){
super(msg);
}
}
class Demo{
int div(int a, int b) throws FuShuException{
if(b<0)
throw new FuShuException("除数出现了负数的情况");
return a/b;
}
}
class ExceptionDemo {
public static void main(String[] args) throws Exception{
Demo d = new Demo();
try{
int x = d.div(4,1);
System.out.println("x="+x);
}catch(FuShuException e){
System.out.println(e.toString());
System.out.println("除数出现负数啦");
}
System.out.println("over");
}
}
自定义异常必须继承Exception的原因?
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点
只有这个体系中的类和对象才可以被throws和throw操作。
7.throws和throw的区别?
1).throws使用在函数上。
throw使用在函数内。
如:class Demo{
int div(int a, int b) throws FuShuException{
if(b<0)
throw new FuShuException("除数出现了负数的情况");
return a/b;
}
}
2).throws后面跟的是异常类,可以跟多个,用逗号隔开。
throw后面跟的是异常对象。
8.Exception中有一个特殊的子类异常RuntimeException运行时异常。
如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明该异常,调用者可以不用进行处理,编译一样通过。
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正,
RuntimeException常见子类:ArithmeticException、NullPointerException、IndexOutOfBoundsException
9.自定义异常时,如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException。
10.对于异常分两种,一种是编译时被检测的异常,另一种编译时不被检测的异常,即运行时异常,RuntimeException及其子类
11.finally代码块,定义一定执行的代码,通常用于关闭资源
eg:
public void method() throws NoException // 抛出新的异常
{
try{
连接数据库;
数据操作;
}catch(SQLException e){
对数据库进行异常处理;
throw new NoException();//新的异常
}finally{
关闭数据库;
}
}
12.异常处理语句格式
catch是用于处理异常的,如果没有catch,就代表异常没有被处理过,如果该异常时检测时异常,那么必须声明
第一种:try{}catch(){}
第二种:try{}catch(){}finally{}
第三种:try{}finally{}
13.覆盖时的异常特点
1).子类在覆盖父类时,如果父类方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类,或者不抛
class AException extends Exception{
2).如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集
3)。如果父类或者接口非方法中没有异常抛出,那么子类在覆盖方法时,也可以不抛出异常,如果子类方法发生了异常,就必须要进行try处理,绝对不能抛
}
class BException extends AException{
}
class CException extends Exception{
}
class Fu{
void show(){
}
}
class zi entends Fu{
void shows() throws BException{//只能抛A或者B异常,不能抛C异常
}
}
13.异常练习
有一个圆形和一个长方形,对于面积如果有非法数值,视为是获取面积出现的问题,问题通过异常来表示
class NoValueException extends RuntimeException{
NoValueException(String message){
super(message);
}
}
interface shape{
void getArea();
}
class Rec implements Shape{
private int len, wid;
Rec(int len, int wid){
if(len<=0 || wid<=0)
throw new NoValueException("出现非法值");
this.len = len;
this.wid = wid;
}
public void getArea(){
return len*wid;
}
}
class{
public static void mian(String[] args){
Rec r = new Rec(-3,4);
r.getArea();
System.out.println("over");
}
}