Java(5-1)

这回我们来说说Java的异常:
我们用一个图来开始:
这里写图片描述

可以发现,所有的异常都是由Throwable继承而来的,下面分为了Error和Exception。

其中Error类曾是结构描述了额Java运行时系统的内部错误和资源耗尽错误。这种错误程序员无能为力,不管了。

所以我们需要关注的是Exception层次的错误,派生与RuntimeException的异常包含以下几种情况:
1)错误的类型转换
2)数组访问越界
3)访问null指针

不是派生于RuntimeException的异常包括:
1)试图在文件尾部后面读取数据。
2)试图打开一个不存在的文件
3)一招给定的字符串查找Class对象,而这个字符串表示类并不存在

还有无法找到类的错误,以及不支持克隆的错误。

Java语言将派生于Error类或RuntimeException类的所有异常称为非受查异常,所有其他的异常称为受查异常

方法应该在其首部声明所有可能抛出的异常,举个例子啊~

public FileInputStream(String name) throws FileNotFoundException

但也不能将所有可能抛出的异常都进行声明。以下四种情况,应该抛出异常:
1.调用一个抛出受查异常的方法,例如FileInputStream构造器
2.程序运行过程中发现错误,并且利用throw语句抛出一个受查异常
3.程序出现错误,例如a[-1] = 0 会抛出一个ArrayIndexOutOfBoundException这样的
4.Java虚拟机和运行时库出现的内部错误。

对于那些可能被他人使用的Java方法,我们可以这样:

class MyAnimation{
    ...
    public Image loadImage(String s)throw IOException
    //假如一个方法可能有多个受查异常类型,我们可以这样
    public ...(String)throw FileNotFoundException,EOFException
}

创建异常类:
在程序中,我们很可能会遇见任何标准异常类都没有能充分描述清楚的问题。这种情况下,就需要我们创建自己的异常类。我们只需要定义一个派生于Exception,或者派生于Exception子类的类例子如下:

class FileFormatException(){}
public FileFormatException(String gripe)
{
    super(gripe);
}

现在,我们就可以抛出自己的异常啦:

String readData(BufferedReader in)throws FileFormatException{
    ...
    while(...)
    {
        if(ch == -1)
        {
            if(n<len) throw new FileFormatException();
        }
        ...
    }
    return s;
}

上面我们说了,如何抛出一个异常。很简单,但是我们还需要学习下关键内容,即如何去捕获异常:
我们需要使用try/catch语句去捕获异常,如下所示:

try
{
    code; more code; more more code;
}
catch(ExceptionType e)
{
    handler for this type
}

如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类,那么:
1.程序将跳过try语句块的其余代码。
2.程序将执行catch子句中的处理器代码。
值得注意的是,如果方法中的任何代码抛出了一个在catch子句中没有声明的异常类型,那么这个方法就会异常退出。

有时候异常并不是一个,如何捕获多个异常呢?

try
{
    code that might throw exception
}
catch(FileNotFoundException e)
{
    emergency action for missing files
}
catch(UnknowHostException)
{
    emergency action for unknown hosts
}
catch(IOException e)
{
    emergency action for all other I/O problems
}

在java7中同一个catch可以捕获多个异常类型,只是中间要用一个 | 分开。
比如 FileNotFoundException | UnknowHostException e 这样。

一种“优雅”地抛出异常的方法:
在catch子句中可以抛出一个异常,这样做的目的是改变异常的类型。但是异常类型往往很多,比如执行servlet代码时候,可能不想知道发生错误的细节,但是希望明确的知道servlet是否有问题。
看个例子:

try
{
    access the database;
}
catch(SQLException)
{
    throw new ServletException("database: " + e.getMessage());
}

这里,ServleException用带有异常信息的文本构造器来构造。
不过,还有一种更“优雅”的处理方法,并且将原始异常设置为新异常的“原因”:

try
{
    access the database
}
catch(SQLException e)
{
    Throwable se = new ServletException("database error");
    se.initCause(e); 
    //当捕获到异常是,可用 Throwable e = se.getCause();
    //重新得到异常
    throw se;
}

强烈建议用这种包装技术,这样可以让用户抛出子系统的高级异常,而不会丢失原始异常的细节。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值