------- android培训、java培训、期待与您交流! ----------
异常:就是程序在运行时出现的不正常的情况。
异常的由来:问题也是现实生活中的一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。
其实就是java对不正常情况进行描述后的对象体现。
对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。
对于严重的,java通过Error类进行描述。
对于Error一般不编写针对代码对其处理。
对于非严重的,java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
异常的体系:
Throwable
Error
通常出现重大问题时,运行的类不存在或者内存溢出等。
不编写针对代码对其处理。
Exception
在运行时运行出现的一些情况,可以通过try catch finally
异常的处理:
java提供了特有的语句进行处理
try
{
需要被检测的代码
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
对多异常的处理:
1.声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2.对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
示例:
class Demo
{
int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
{
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)
{
System.out.println("除零了");
System.out.println(e.getMessage());//打印的是异常信息/by zero;
System.out.println(e.toString());//异常名称: 异常信息。
e.printStackTrace();//异常名称,异常信息,异常出现的位置。
//其实jvm默认的异常处理机制,就是在调用printStackTrace方法,打印异常在堆栈的跟踪信息。
}
System.out.println("over");
}
}
class Demo
{
int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。
{
int[] arr = new int[a];
System.out.println(arr[4]);//角标越界
return a/b;
}
}
class ExceptionDemo1
{
public static void main(String[] args) throws ArithmeticException
{
Demo d = new Demo();
try
{
int x = d.div(4,0);
System.out.println("x="+x);
}
catch (ArithmeticException e)//Exception e = new ArithmeticException();
{
System.out.println(e.toString());
System.out.println("被零除了!!!");
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println(e.toString());
System.out.println("角标越界了!!!");
}
System.out.println("over");
}
自定义异常:
因为项目中后出现特有的问题,而这些问题并未被java所描述并封装对象。
所以对于这些特有的问题可以按照java的对问题封装的思想,将特有的问题进行自定义的异常封装。
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
要么在内部try catch处理。
要么在函数上声明,让调用者处理。
简单一句话:一般情况下,函数内出现异常,函数上需要声明。
发现打印的结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义所属信息。
如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,
将异常信息传递给父类通过super语句。那么就可以直接通过getMessage方法获取自定义的异常信息。
自定义异常:
必须是自定义类继承Exception。
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具有可抛性。这个可抛性是Throwable这个体系中独有的特点。
只有这个体系中的类和对象才可以被throw和throws操作。
throw和throws的区别:
throws使用在函数上。(什么事函数上,就是要写在小括号的大括号之间)
throw使用在函数内。
throws后面跟的是异常类,可以跟多个,用逗号隔开。
throw后面跟异常对象。
异常处理的原则:
1.函数内容如果抛出需要检测的异常:
--那么函数上必须要声明
--否则必须在函数内用try catch捕捉,否则编译失败。
2.如果调用到了声明异常的函数:要么try catch要么throws,---》否则编译失败。
3.什么时候catch,什么时候throws 呢?
功能内容可以解决,用catch。
解决不了,用throws告诉调用者,由调用者解决 。
4.一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。
内部又几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。
5.多个catch,父类的catch放在最下面。
6.catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。
7.当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常。或者 异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,让调用者知道,并处理。也可以将捕获异 常处理后,转换新的异常。
Try{Throw new AException();}
Catch(AException e){
Throw e;}
Try{Throw new AException();}
Catch(AException e){
//对AException处理。
Throw new BException();
}//汇款例子
异常的注意事项:
1.子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。
2. 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
注意:如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try。
class FuDhuException extends Exception
{
private int num;
FuShuException(String msg,int num)
{
super (msg);
this.num=num;
}
public int getNum()
{
return num;
}
}
class Demo
{
int div(int a,int b)throws FuDhuException
{
if (b<0)
throw new FuDhuException("出现了除数是负数的情况----- / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。
return a/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(4,1);
System.out.println("x="+x);
}
catch (FuDhuException e)
{
System.out.println(e.toString());
//System.out.println("除数出现负数了");
System.out.println("出现的负数是:"+e.getNum());
}
System.out.println("over");
}
}
异常的分类:
1.编译时被检测异常:
只要是Exception和其子类都是,除了特殊子类RuntimeException体系。
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。
这样的问题都可以针对性的处理。
2.编译时不检测异常(运行时异常):
就是Exception中的RuntimeException和其子类。
这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引 发了内部状态的改变导致的。
那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让 调用者对代码进行修正。
异常RuntimeException
Exception中有一个特殊的子类异常RuntimeException -->运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
自定义异常时:如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException。