每日总结[12] 20191205 JavaSE复习-异常处理机制

1.头脑风暴:把我能想到的写下来。
当程序出现了错误,而不对它进行处理时,程序将会终止并报错,为了不影响后续程序的执行,可以采用异常处理机制Exception Handler。将异常进行抛出throw,并将控制权交给处理器,这样程序就不会终止了。

[补:异常处理的任务就是将控制权从错误产生的地方转移给能够处理这种情况的错误处理器。
在Java中,如果某个方法不能采用正确的途径完成它的任务,就可以通过另外一个路径退出方法。在这种情况下,方法并不返回任何值,而是抛出一个封装了错误信息的对象。
遇到异常就会入异常栈,Throwable类有个方法:printStackTrace就是打印栈轨迹。]

异常是个类:Throwable。其下有两个子类:Error类和Exception类,

其中Error类是系统的错误,比如JVM崩溃、线程死锁等,是不需要捕获或抛出的,我们处理不了的。任何程序都具有出现这种错误的潜能,而也是不能控制的。

[改:虚拟机错误和系统崩溃时。]
[补:Error类描述了Java运行时系统的内部错误和资源耗尽错误。]

而Exception类有两个子类:CheckedException(受查异常)和RuntimeException。

CheckedException常见子类有SQLException和IOException。要求对受查异常必须进行捕获或是抛出处理。编译器会检查是否为受查异常提供了处理器。

[补:受查异常:在编译运行之前,就要知道是否发生异常,这类异常必须进行捕获,否则无法通过编译。]

除了受查异常以外的异常都属于非受查异常,非受查异常可以不被捕获和声明。
非受查异常有两种:一种是无法处理的——Error类,一种是希望被避免的(如编写程序时就有检查) ——RuntimeException类。

RuntimeException的常见子类有 ClassCastException,(类型转换异常),ArrayIndexOutOfBoundsException(数组下标越界),Arthr???(运算异常),NullPointException(空指针异常) 。RuntimeException属于非受查异常。

[改:ArithmeticException运算异常。]

“RuntimeException”遇到的问题是代码(你)的问题。
[补:“由于程序错误导致的。”
在运行前无法确定是否异常。
不运行时不知道它出错的。
异常都是发生在运行期。
编译时出现的错误叫语法错误。
]

可以在方法中声明异常:返回值 方法名 (形参) throws …Exception
[补:向上声明只是告诉调用者,在使用该方法时,应当对那些异常进行处理。]

注意:子类如果覆写了父类的方法,它抛出的异常类型必须小于等于父类方法中抛出的异常。

[补:如果父类没有抛出任何受查异常,那么子类也不能抛出任何受查异常。]

除了抛出异常,还可以捕获异常,

try { 可能出现异常的代码块 }
catch ( 可能出现的异常) { 处理 }
finally {最终执行的}

如果在try块中没有遇到catch()中捕获的异常,那么就会在执行完try块后,返回主调函数 即调用了该方法,需要求该方法返回值的地方 前,执行finally块,执行完finally块,才返回try块中的值, 调用结束。因此,如果finally中有return语句,就会覆盖掉原来try块中的返回值,因此需要避免在finally块中写return。
如果try中遇到了catch()中捕获的异常,那么就会停止try中的执行,跳转去执行catch块中的内容,而在该方法返回主调函数前,仍会执行finally块的内容。

[总结:“在方法返回前,finally子句的内容将被执行。”]

只有遇到一种情况时finally块是不会执行的——当遇到System.exit(0)退出虚拟机时。

2.补充:
(1)用户可以创建自己的异常类。
(2)
关于在finally块种修改return值的问题:
上代码:

public class SubClass
{
    public static int testFinally1()
    {
        int result=1;
        try
        {
            result=2;
            return result;
        }
        finally {
            result=3;
            System.out.println("execute finally1");
        }
    }
    public static StringBuffer testfinally2()
    {StringBuffer s=new StringBuffer("Hello");
    try
    {
        return s;
    }

    catch (Exception e)
    {return null;}
    finally {
        s.append("World");
        System.out.println("execute finally2");
    }
    }



    public static void main(String[] args) {
        int resultVal = testFinally1();
        System.out.println(resultVal);
        StringBuffer resultRef = testfinally2();
        System.out.println(resultRef);
    }}

运行结果为
控制台输出:
execute finally1
2
execute finally2
HelloWorld

分析: 通过Javap分析生成的字节码可以知道,在正常代码块执行完成后,会将需要返回的值 result=2 存储到单独的局部变量中,而finally操作的局部变量仍是返回值最初存入的局部变量 这时那个result=3 。由于返回值 result=2 做了备份,因此,如果是修改基础类型,不会对方法的返回值造成影响;如果是修改引用类型,会修改程序的返回结果。

发布了47 篇原创文章 · 获赞 1 · 访问量 1267

猜你喜欢

转载自blog.csdn.net/weixin_41750142/article/details/103411868