返回列表 发新帖

【Android入坑系列教程】48.异常(二)---面向对象

[复制链接]

62

主题

722

回帖

2756

积分

大学生

Rank: 5Rank: 5

金币
2029
好评
12
信誉
100

考神

发表于 2019-4-6 12:54:29 | 显示全部楼层 | 阅读模式  来自 四川
本帖最后由 pansong291 于 2019-4-2 13:25 编辑

上篇:47.异常(一)---面向对象
下篇:49.异常(三)---面向对象

注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!


自定义异常与 Throw 关键字
我们通过查阅 JDK 文档资料,就能看到,Exception 类是 java.lang.Throwable 类的子
类,Exception 类继承了 Throwable 类的所有方法。其实,我们在实际应用中,是使用
Exception 的子类来描述任何特定的异常的。Exception 类是所有异常类的父类,Java 语言
为我们提供了许多 Exception 类子类,分别对应不同的异常类型,如我们在前面已经看到过
以下几个异常。
ArithmeticException(在算术运算中发生的异常,如除以零)
NullPointerException(变量还没有指向一个对象,就引用这个对象的成员)
ArrayIndexOutOfBoundsException(访问数组对象中不存在的元素)
除了系统提供的异常,我们也可以定义自己的异常类,自定义的异常类必须继承
Exception 类。假设我们在上面程序的 devide 函数中,不允许有负的被除数,当 devide 函
数接收到一个负的被除数时,程序返回一个自定义的异常(这里就叫负数异常吧!)通知调
用者。我们可以这样定义这个负数异常类。
class DevideByMinusException extends Exception
{
    int devisor;
    public DevideByMinusException(String msg,int devisor)
    {
        super(msg);
        this.devisor = devisor;
    }
    public int getDevisor()
    {
        return devisor;
    }
}
Java 是通过 throw 关键字抛出异常对象的,其语法格式是
throw 异常对象;
如果我们的程序想跳转,我们可以抓住自己抛出的异常。否则,则此方法应声明抛出异
常,而由该方法的调用者负责处理。
如果我们要在 devide 函数接收到的第二个参数(也就是被除数)为负数时,向调用者
抛出自定义的 DevideByMinusException 对象,程序代码如下:
class Test
{
    public int devide(int x, int y) throws ArithmeticException, DevideByMinusException
    {
        if(y < 0)
            throw new DevideByMinusException("被除数为负", y);
            //这里抛出的异常对象,就是调用者在 catch(Exception e){}语句中接收的变量 e。
        int result = x/y;
        return x/y;
    }
}
我们能够看到,上面的代码中,devide 方法声明时抛出了两个异常。java 中一个方法
是可以被声明成抛出多个异常的。
下面再来看看调用程序应该如何对 devide 方法中的多个异常作出处理。
public class TestException
{
    public static void main(String [] args)
    {
        try
        {
            int result = new Test().devide( 3, 0 );
            //int result = new Test().devide( 3, -1 );
            //int result = new Test().devide( 3, 1 );
            System.out.println("the result is " + result );
        }
        catch(DevideByMinusException e)
        {
            System.out.println("program is running into DevideByMinusException");
            System.out.println(e.getMessage());
            System.out.println("the devisor is " + e. getDevisor());
        }
        catch(ArithmeticException e)
        {
            System.out.println("program is running into ArithmeticException");
            System.out.println(e.getMessage());
        }
        catch(Exception e)
        {
            System.out.println("program is running into other unknowned Exception");
            System.out.println(e.getMessage());
        }
        System.out.println("program is running here ,that is normal !");
    }
}
上面的程序使用一个 try 后面跟着多个 catch 来捕捉异常,每一个 catch 可以处理一个
不同的异常类型。如果我们调用 devide(3,0),将发生 ArithmeticException 异常,程序将跳
转至 catch(ArithMeticException e)代码块中执行。如果我们调用 devide(3,-1),将发生
DevideByMinusException 异常,程序将跳转至 catch(DevideByMinusException e)代码块中
执行。如果在 devide 方法中发生了 ArithmeticExceptionDevideByMinusException 之外的
任何其他异常,程序将跳转至 catch(Exception e)代码块中执行,也就是还没有由前面的
catch 处理的异常,都将由 catch(Exception e)代码块处理,不是因为该语句是最后一个
catch,而是由于 Exception 是所有异常类的父类,从语法上来讲,是能够处理所有异常的。
所以,各种 catch 代码块的放置顺序非常重要,catch(Exception e)不能放在其他 catch
句的前面,否则后面的 catch 永远得不到执行,就没有什么意义了。大家可以用 ifelse if
else ifelse 结构去考虑 try...catch 问题。读者可以逐一去掉程序中被注释的 devide
语句的注释符,注释掉其他的 devide 语句,对比观察运行结果。
多学两招:
我们可以在一个方法中使用 throwtrycatch 语句来实现程序的跳转,下面是描述这
种方法的一段简要程序代码:
void fun()
{
    try
    {
        if(x==0)
            throw new YyyException("Yyy"); //跳转到代码块 1 处
        else if(x==1)
            throw new XxxException("Xxx"); //跳转到代码块 2 处
    }
    catch(YyyException e)
    {
        代码块1
    }
    catch(XxxException e)
    {
        代码块2
    }
}

finally 关键字
trycatch 语句后,我们还可以有个 finally 语句,finally 语句中的代码块不管异
常是否被捕获总是要被执行的。我们将上面的程序作如下修改,来看看 finally 语句的用法
与作用。
public class TestException
{
    public static void main(String [] args)
    {
        try
        {
            int reslut = new Test().devide( 3, 0 );
            //int reslut = new Test().devide( 3, -1 );
            //int reslut = new Test().devide( 3, 1 );
            System.out.println("the result is" + result );
            //return ;
        }
        catch(DevideByMinusException e)
        {
            System.out.println("program is running into DevideByMinusException");
            System.out.println(e.getMessage());
            System.out.println("the devisor is " + e. getDevisor());
            System.exit(0);
        }
        catch(ArithMeticException e)
        {
            System.out.println("program is running into ArithMeticException");
            System.out.println(e.getMessage());
            return ;
        }
        catch(Exception e)
        {
            System.out.println("program is running into other unknowned Exception");
            System.out.println(e.getMessage();
        }
        finally
        {
            System.out.println("program is running into finally");
        }
        System.out.println("program is running here ,that is normal !");
    }
}
爱思考的读者也许会问:程序中的最后一句 System.out.println("program is running here ,that is normal !");
不论有没有异常发生,该语句都会执行,那何必还用 finally 语句呢?
finally 还是有其特殊之处的,即使 try 代码块和 catch 代码块中使用了 return 语句
退出当前方法或 break 跳出某个循环,相关的 finally 代码块都要执行,读者可以逐一去掉
程序中被注释的 devide 语句的注释符,注释掉其他的 devide 语句,对比观察运行结果。
finally 中的代码块不能被执行的唯一情况是:在被保护代码块中执行了System.exit(0)
每个 try 语句必须有一个或多个 catch 语句对应,try 代码块与 catch 代码块及 finally
代码块之间不能有其他语句。如下面的代码是非法的。
try
{
    ……
}
x = 3 + 5; //代码位置是非法的
catch(Exception e)
{
    ……
}

上篇:47.异常(一)---面向对象
下篇:49.异常(三)---面向对象
回复

使用道具 举报

103

主题

4218

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
582
好评
36
信誉
102

MT论坛帅哥2019-5.1节快乐MT论坛最佳新人考神MT论坛新人

发表于 2019-4-6 13:04:30 来自手机  | 显示全部楼层  来自 湖北
我不信这是你打的,说罢从哪里搬来的?
回复

使用道具 举报

133

主题

4852

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
15
好评
116
信誉
100

考神MT论坛活跃会员MT论坛侠客MT论坛新人

发表于 2019-4-6 15:09:41 来自手机  | 显示全部楼层  来自 湖北
2910637794 发表于 2019-4-6 13:04
我不信这是你打的,说罢从哪里搬来的?

就算是搬砖的,我也佩服整整48篇帖啊
已有1人评分金币 理由
焱妃 + 1 6

查看全部评分 总评分:金币 +1 

回复

使用道具 举报

6

主题

1934

回帖

6550

积分

硕士生

Rank: 6Rank: 6

金币
2823
好评
1
信誉
100
发表于 2019-4-6 16:41:02 来自手机  | 显示全部楼层  来自 广东
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表