java学习之异常(二)

异常的类别

超类 Throwable:所有异常由 Throwable 类继承而来,它分为

  • Error类:描述 java 运行时系统的内部错误和资源耗尽错误
  • Exception类:又分解为
    • RunTimeException类:由程序错误导致的异常
    • 其它异常:程序本身没问题,但出现像I/O错误等问题导致的异常

通常来讲,如果程序出现 RunTimeException 异常,那么就一定是你的问题,如发生错误的类型转换、数组访问越界、访问空指针等


异常的声明

方法应该在其首部声明可能抛出的异常,如某个类的构造器声明

class Demo
{
    public FileInputStream(String s)throws FileNotFoundException
}

当发生问题时,构造器不会初始化一个新的 FileInputStream 对象,而是抛出一个 FileNotFoundException 类对象,然后系统开始搜索异常处理器进行处理。

在什么情况下应该抛出异常:

  1. 调用一个抛出已检查异常的方法,如,FileInputStream 构造器
  2. 程序运行过程中发现错误,并利用 throw 语句抛出一个已检查异常
  3. 程序本身出现错误,如,a[-1]=0 会抛出一个 ArrayIndexOutOfBoundsException 的未检查的异常
  4. java虚拟机和运行时库出现的内部错误

出现前两种情况,必须告诉调用该方法的程序员有可能抛出异常,在方法的首部声明;
如果一个方法有可能 抛出多个异常,那么应该列出所有的异常类,并以逗号隔开
对于 java 的内部错误(从 Error 继承的类)不需要声明,因为我们对它们没有任何控制能力

class ImageDemo
{
    ...
    public Image loadImage(String s)throws FileNotFoundException,EOFException
    {
        ...
    }
}

注意:C++中,如果没有给出 throw 说明,函数可能会抛出任何异常,但在 java 中,没有 throws 声明符的方法不能抛出任何已检查异常。


如何抛出异常

对于一个已存在的异常类,通常的做法:
1. 找到了一个合适的异常类
2. 创建这个类的一个对象
3. 将对象抛出

当方法抛出异常后,该方法就不可能返回到调用者。

String readData(Scanner in)throws EOFException
{
    ...
    while(...)
    {
        if(!in.hasNext())// EOF encounterd
        {
            if(n < len)
            {
                String gs = "Content-length:" + len + ",Received:" + n;
                throw new EOFException(s);
            }
        }
        ...
    }
    return s;
}

注意:throws 和 throw 的区别

  • throws 使用在函数上(小括号与大括号之间),throw 使用在函数内。
  • throws 后面接的是异常类,且可以有多个,throw 后面接的是异常对象。

自定义异常类

有时,在某个特殊的场景中,需要根据需求人为的设计出符合当前要求的异常类,来帮助解释问题。此时我们需要做的只是定义一个继承于 Exception 类或者其子类的类,如定义一个继承于 IOException 的类。

RunTimeException

class FileFormatException extends IOException
{// 习惯上,所有继承的异常类都支持一个默认的构造器和一个带有详细描述信息的构造器
    public FileFormatException()// 构造的对象没有详细的描述信息
    {
        super();
    }
    public FileFormatException(String s)// 带有详细的描述信息
    {
        super(s);
        // 父类中已经把异常信息测操作完成了,子类在构造时,将异常信息通过 super 传递给父类,就能直接由 getMessage 方法获取自定义异常的信息
    }
}

String readData(BufferReader in)throws FileFormatException
{
    ...
    while(...)
    {
        if(ch == -1)// EOF encounterd
        {
            if(n < len)
                throw new FileFormatException(...);
        }
        ...
    }
    return gs;
}

特殊的子类异常

对于 Exception 类,如果没有在函数上声明,那么在函数内抛出异常时会编译失败。但是Exception 中有一个特殊的子类异常 RunTimeException(运行时异常)。

RunTimeException
RunTimeException

之所以会这样,是因为不需要让调用者来处理该异常,当异常发生,虚拟机希望程序停止,因为运行时出现了无法继续运算的情况,虚拟机希望程序停止后,程序员能对代码进行修正。

class Demo
{
    int div(int a, int b)throws ArithmeticException// ①
    {
        return a/b;
    }
    /*int div(int a, int b)// ②
    {
        if(b==0)
            throw new ArithmeticException("除零啦");
        return a/b;
    }*/
    /*int div(int a, int b)// ③
    {
        if(b==0)
            throw new Exception("除零啦");
        return a/b;
    }*/
}

class ExceptionDemo
{
    public static void main(String[] args)
    {
        Demo d = new Demo();

        int x = d.div(4,0);
        System.out.println("x=" + x);

        System.out.println("END!");
    }
}
/*
特殊情况是 ①或②单独出现时都能编译成功,③,编译会失败。
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值