关于异常的处理和设计推荐博客
讨论子类重写父类方法的时候,如何确定异常抛出声明的类型。下面是三点原则:
1)父类的方法没有声明异常,子类在重写该方法的时候不能声明异常;(如果子类抛出的是未检查异常,则个数没有限制)
2)如果父类的方法声明一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类;
3)父类就算没有声明异常子类也是可以声明的,不过只能是声明运行时异常(未检查异常),且个数没有限制.但是当父类抛出了检查异常,则子类不能抛出比父类数量更多的检查异常且子类抛出去的检查异常不能比父类的”大”,(这里的请参照(2)理解)。
有一点需要明确的说明一下,重写要求子类扔出的异常不能比父类多但是未检查异常则是可以的。即
//父类
import java.io.FileNotFoundException;
public class TestException_1 {
//此方法扔出的是为检查异常可以不声明
public void test(){
throw new NullPointerException();
}
//此方法扔出的是已检查异常要声明
public void test1() throws FileNotFoundException{
throw new FileNotFoundException("没有找到文件");
}
}
//子类
/**典型的RuntimeException包括NullPointerException、
* IndexOutOfBoundsException、IllegalArgumentException等。
* 典型的非RuntimeException包括IOException、SQLException等。
* @author Administrator
*/
import java.io.FileNotFoundException;
//TestException_2类继承自TestException_1,其中test()方法重写了TestException_1类的test()方法
//如果方法是重写关系,那么子类扔出的异常不能多于父类的异常。但是如果子类扔出的异常是未检查异常,那么子类可以扔出
public class TestException_2 extends TestException_1{
//重写要求子类扔出的异常不能比父类的多,但是未检查异常则是可以的
public void test() throws NullPointerException, IndexOutOfBoundsException, IllegalArgumentException{
throw new NullPointerException();
}
public void test1() throws FileNotFoundException{
throw new FileNotFoundException("没有找到那个文件");
}
}
关于链式异常
链式异常就是指异常链,在java中异常之间是可以关联的,组成一个异常链。可以使用initCause方法将两个异常关联起来。也可以不用initCause方法。
public class ChainExcDemo {
static void demoproc(){
NullPointerException e = new NullPointerException("空指针");
e.initCause(new ArithmeticException("引起空指针的原因"));
throw e;
}
public static void main(String[] args){
try {
demoproc();
} catch (NullPointerException e) {
System.out.println("捕捉到:" + e);
Exception cause = (Exception)e.getCause();
System.out.println("初始的原因:" + cause);
}
}
}
//这里将空指针异常和ArithmetricException结合在一起。
编译运行结果为:
另外一个链式异常例子
/**
* main方法调用method1,method1调用method2,method2抛出一个异常。该异常被method1的catch块
* 所捕获,并被method1中的catch块中的语句包装成一个新异常。该异常被抛出,并在main方法中的catch块中被捕获。
* 首先显示从method1中抛出的新异常,然后显示从method2中抛出的原始异常。
* @author Administrator
*
*/
public class ChainedExceptionDemo {
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void method1() throws Exception{
try {
method2();
} catch (Exception e) {
throw new Exception("New info from method1", e);
}
}
public static void method2() throws Exception{
throw new Exception("New info from method2");
}
}
关于自定义异常类
如果想要自定义一个异常,需要创建一个类,让其继承Exception类或者Exception类的子类就可以了。一般当一个类继承了异常类之后,在重写方法的时候,根据自己的选择进行重写下面的函数,(根据自己的需要来选择)(下面自定义异常类叫做DataAccessException)
public class DataAccessException extends Exception {
public DataAccessException() {
super();
}
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
public DataAccessException(String message) {
super(message);
}
public DataAccessException(Throwable cause) {
super(cause);
}
}
在这里给出一个自定义异常类的源码
程序一:
public class InvalidRadiusException extends Exception{
private double radius;
public InvalidRadiusException(double radius) {
super("Invalid radius" + radius);
this.radius = radius;
}
public double getRadius(){
return radius;
}
}
程序二:
public class CircleWithCustomException {
private double radius;
private static int numberOfObjects = 0;
public CircleWithCustomException() throws InvalidRadiusException {
this(1.0);
}
public CircleWithCustomException(double newRadius) throws InvalidRadiusException{
setRadius(newRadius);
numberOfObjects++;
}
public double getRadius(){
return radius;
}
public void setRadius(double newRadius) throws InvalidRadiusException{
if (newRadius >= 0)
radius = newRadius;
else
throw new InvalidRadiusException(newRadius);
}
public static int getNumberOfObjects(){
return numberOfObjects;
}
public double findArea(){
return radius * radius * 3.14159;
}
}
程序三(测试类):
public class TestCircleWithCustomException {
public static void main(String[] args) {
try {
new CircleWithCustomException(5);
new CircleWithCustomException(-5);
new CircleWithCustomException(0);
} catch (InvalidRadiusException e) {
System.out.println(e);
}
System.out.println("number of objects created:" +
CircleWithCustomException.getNumberOfObjects());
}
}
上述代码编译运行结果: