Java异常学习笔记(四)

时间:2023-02-25 21:02:19

Java异常学习笔记之----自定义异常

上一篇  Java异常学习笔记(三)

自定义异常

Java为我们定义了很多异常,但是很多实际开发中需要使用的异常在Java中并不存在,这是需要我们自定义异常。

自定义异常即自定义类继承自Exception或者RuntimeException

实现很简单

public class MyException extends RuntiemException
{

}
这样就定义了一个简单得异常类,下面使用自定义异常

pubic void static checkNum(int num)
{
if(num<0)//假设num<0时抛出自定义异常
{
throw new MyException();
}

}
pubic void static main(Stirng []args)
{
try
{
checkNum(-1);
}catch(MyException e)
{
e.printStatckTrace();//由于MyException继承自RuntimeException,而RuntimeException终究继承于Throwable类,所以具有printStackTrace()方法。
}
}

为自定义异常添加异常信息

在上面的示例中,MyException完全继承自RuntimeException没有重写任何父类方法。这样的自定义异常是完全可用的。当然我们可以重写父异常类的一些方法来更完全地自定义我们的异常类。

例如:如果我们需要在自定义异常中携带一些异常信息(这里的异常信息不是指异常类名和异常行号,而是人为添加的信息,如发生除以0的异常,在控制台输出“不能除以0”这样的异常信息)。使用方式我们希望像API中的异常类一样,像下面这样,在new中直接传入异常信息。如下:

if(num<0)
{
throw new MyException("数字不能小于0!");
}
这样抛出的异常到了main函数中执行e.printStackTrace()直接能够输入异常信息。

由于:

1. printStackTrace()实际输出的toString()和fillInStackTrace()的结果,而toString()中包含的异常信息实际是异常类Throwable中的字段detailMessage: String。

2. detailMessage的初始化在Throwable的构造函数中。

3. detailMessage 为 private 的。

所以,要实现以上需要的功能,只需要给出自定义异常类的无参构造函数和有参构造函数,然后调用父类的构造函数初始化detailMessage即可。

public class MyException extends RuntimeException
{
MyException(){}
MyException(String msg)
{
super(msg);//调用父类的构造函数出事话detailMessage
}
}


重写父类方法

当父类方法有throws时,如果子类重写父类的方法,不能抛出比父类更宽泛的异常。

什么是更宽泛的异常?

答:只要是子类抛出的异常类不在父类异常类及其所有子类中包含,都是更宽泛的异常。

注意:这里只针对编译时异常。经过试验我发现:RuntimeException及其子类在这条规则中异常范围=0。也就是RuntimeException及其子类

下面这个例子将告诉我们这个:

class Fu {
public void method() throws UnknownGroupException // 父类throws一个编译时异常
{
}
}

class Zi extends Fu {

public void method() throws ArithmeticException, RuntimeException// 子类throws运行时异常
{
}
}

public class ExceptionDemo {
public static void main(String[] args) {
Fu fu = new Fu();
Zi zi = new Zi();
try {
fu.method();
} catch (UnknownGroupException e) {//throws一个编译时异常必须catch或重新throws

e.printStackTrace();
}
zi.method();
System.out.println("程序顺利结束");// 运行后程序顺利结束
}
}