Java基础之异常处理篇
先介绍几种经常会碰到的异常:
*RuntimeException:执行时异常,也叫不检查异常,它包括以下几种异常。
{ArithmeticException算术异常,整数的除零操作会导致该异常。
NullPointerException空指针异常,当对象没有实例化时,就试图通过该对象访问其数据和或方法。
ArrayStoreException数组存储空间不足异常。
ArrayIndexOutOfBoundException数组下标越界异常。
*IOException:输入/输出异常。
{ClassNotFoundException、NoSuchMethodException、FileNotFoundException}
一、异常的概念:
异常:就是程序在运行时出现不正常情况。
异常的由来:Java对不正常情况进行描述进行描述,封装成对象。
对于不正常情况的划分:两种:一种是error,一中是exception,而Java中对于严重的情况用Error类描述,一般不编写针对性的代码对其进行处理;对于非严重的情况用Exception类描述,一般会使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。比如不正常情况信息,引发原因等。这些共性内容向上抽取就形成一个类,这个类就是他们的父类—Throwable。
二、异常的处理:
Java提供了特有的语句进行处理。(try-catch-finally;try-catch;try-finally)
try
{
需要被检测的代码;
}
catch(异常类变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;//注意:因为finally的一定执行性,它会用于关闭连接和关闭资源。只有在其前面执行了exit();时,它才不会被执行。
}
eg.
class Demo
{
intdiv(int a,int b)//demo对象实例化后接受到try中被检测代码中调用对象方法的参数进行运算出现异常,此时ArithmeticException这个类的对象被创建,并抛给了try。
{
returna/b;
}
}
class ExceptionDemo
{
publicstatic void main(String[] args)
{
Demod = new Demo();
try
{
intx = d.div(4,0); //try接收ArithmeticException的对象并抛给catch
System.out.println("x="+x);//这句代码没有执行。
}
catch(Exception e) //catch接收ArithmeticException的对象并处理。
{
System.out.println("除数为零");
System.out.println(e.getMessage());//异常信息;
System.out.println(e.toString());//异常名称:异常信息。
e.printStackTrace();//异常名称,异常信息,异常出现的位置。
} //其实JVM默认的异常处理机制,就是在调用printStackTrace方法。
System.out.println("over");
}
}
三、异常的声明:
异常的声明要有到throws和throw两个关键字,throws是在方法上抛的,而throw是在方法内抛的。throws后面跟的是异常类,可以跟多个,用逗号隔开;
throw后面跟的是异常对象,可以带异常信息。
当方法可能会出错时,那么就要声明,此时一旦出错,catch就会捕捉对象进行处理,便于提高安全性。
eg.
class Demo
{
intdiv(int a,int b) throws Exception//在功能上通过throws声明了该功能有可能会出问题。
{
returna/b;
}
}
class ExceptionDemo
{
publicstatic void main(String[] args)
{
Demod = new Demo();
try
{
intx = d.div(4,0);
System.out.println("x="+x);
}
catch(Exception e)
{
System.out.println(e.toString()); }
}
System.out.println("over");
}
}
四、多异常处理:
1、声明异常时,建议声明更为具体的异常。这样的处理更具体。
2、对方声明几个异常,就对应有几个catch块,不要定义多余的catch块,如果有多个catch块中的异常出现继承关系,父类catch块放在最下面。
建议在进行catch处理时,catch中一定要定义具体的处理方式。不要简单定义一句e.printStackTrace();也不要简单的就书写出一条输出语句。
eg.
class Demo
{
intdiv(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException
{
int [ ] arr = new int[a] ;
System.out.println(arr[4]);
return a/b;
}
}
class ExceptionDemo
{
publicstatic void main(String[] args)
{
Demod = new Demo();
try
{
intx = d.div(4,0);
System.out.println("x="+x);
}
catch(ArithmeticException e)
{
System.out.println(e.toString()); }
}
catch (ArrayIndexOutOfBoundsExceptione)
{
System.out.println(e.toString()); }
}
System.out.println("over");
}
}
五、自定义异常:
由于项目中会出现特有的问题,而这些问题并未被Java所描述并封装成对象,所以对于这些特有的问题可以按照Java对问题封装的思想将特有问题惊醒自定义异常封装。
当在方法内部出现了throw抛出异常对象时,那么就必须给出对应的处理动作,要么在内部try catch处理,要么在函数上声明让调用者处理。
一般情况在方法内部出现异常需要在方法上声明。
发现打印的结果中只有异常的名称,却没有异常信息,因为自定义的异常并未定义信息。
如何定义异常信息?因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递给父类通过super语句,那么就可以直接通过getMessage方法获取自定义的异常信息。
自定义异常必须继承Exception,因为只有Throwable这个体系中的类和对象才能被throws和throw操作。
.
eg.
class FuShuException extends Exception
{
FuShuException(Stringmsg)
{
super(msg);
}
}
class Demo
{
int div(int a,int b) throws FuShuException
{
If(b<0)
throw new FuShuException(“出现了除数是负数的情况”);
returna/b;
}
}
class ExceptionDemo
{
public static void main(String[] args)
{
Demod = new Demo();
try
{
intx = d.div(4,-1);
System.out.println("x="+x);
}
catch(FuShuException e)
{
System.out.println(e.toString()); }
}
System.out.println("over");
}
}
六、RuntimeException:
作为Exception的子类,该异常为运行时异常,如果在方法中抛出该异常,方法上不用声明,编译也可通过。如果在方法上声明该异常,调用者可以不用进行处理,编译一样通过。之所以不用方法声明,是因为不需要让调用者处理。当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
自定义异常时,如果该异常的发生,无法在继续进行运算或者就是想让程序停下来,就让自定义异常继承RuntimeException。
对于异常分为两种:
编译时被检测的异常(一定要在方法上声明,要么处理,要么继续抛);
编译时不被检测的异常(RunTimeException及子类)。
七、异常在子父类覆盖中的体现:
*子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或该异常的子类。
*如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集。
*如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类发生了异常,就必须进行try处理,绝对不能抛。