课程学习--JavaSE--后端(第3期):异常处理

异常

异常,即不正常的事或物。
而在程序范畴中,异常是指使程序无法正常运行的错误或外部问题。

Throwable 类

在Java中,当程序无法正常运行时,通常是出现了错误或者异常。

这时JVM会开始判断,如果是异常,则会创建相应的异常实例,然后抛出给调用者。如果是错误,则进行报错。

这里提到了错误和异常,Java语言将他们定义为Error和Exception类,他们都继承自Throwable类,继承关系如下:

继承关系图

这里列举一些常见的Error和Exception子类:

父类类名相关信息
ErrorOutOfMemoryError内存耗尽
ErrorNoClassDefFoundError无法加载某个Class
ErrorStackOverflowError栈溢出
RuntimeException(illegalargumentexception)NumberFormatException数值类型的格式错误
RuntimeExceptionNullPointerException对某个null的对象调用方法或字段
RuntimeExceptionIndexOutOfBoundsException数组索引越界
IOExceptionFileNotFoundException未找到文件
IOExceptionSocketException读取网络失败

异常处理

Java中,异常的出包含两种,一种是捕获,另一种是抛出。

捕获异常

语法:try...catch...finally

try{

}catch (Exception e){
	e.printStackTrace();
}finally {

}

总结:

  1. try块内某行代码出现异常时,该行代码后的代码将不再被执行,直接进入catch块或者finally块。
try{quan
	// do sth               --√
    // do sth               --√
    // sth wrong            --Oops!
    // break out            --×
    // not to do this       --×
}catch (Exception e){
	e.printStackTrace(); // --√
}finally {
                         // --√
}
  1. 通常不用分步捕获,而用Exception类统一捕获,然后用printStackTrace打印堆栈追踪。

  2. finally块的代码将作为函数复制于在try和catch的最后,并在return或throw之前。

  3. 通常情况下,finally中不使用return/break/continue/throw/goto跳转语句,因为这会导致try或catch中的异常不被捕获以及return失效。

  4. finally块内代码在某些情况下不会执行,如:块内异常;线程死亡;进程结束;硬件问题。

注意:

  1. 请重视空指针异常,切记先判断是否非空,在进行调用。
  2. finally的经典应用为文件读写操作时的 关闭流
  3. finally还有一个细节需要重视!细节就是finally里对基本数据类型参数的操作采用的是值传递,对引用类型参数的操作为引用传递。
抛出异常
异常传播

当某个方法抛出了异常时,如果当前方法没有捕获异常,异常就会被抛到上层调用方法,直到遇到某个try ... catch ...将其捕获为止。

抛出处理

抛出异常有两种定义方法,它们分别是throw和throws。

/**
 * Example for throw & throws
 * @throws Exception
 */
public static void doSthDangerous() throws Exception{
    throw new Exception();
}

面试题

  1. 主函数catch块中抓到的是哪个异常?
package cn.charliejohn.handlexexception;

public class Helloxexceptionx1 {
    public static void main(String[] args) {
        try{
            System.out.println("The answer is " + sthDangerous()+".");
        }catch(Exception e){
            // 答:
            // 1. 主函数中没能捕获到异常,因为finally在抛异常前return true。
            System.out.println("Exception from main.");
            e.printStackTrace();
        }
    }

    public static boolean sthDangerous(){
        try {
            throw new Exception("Try in sthStrange.");
        } finally {
            return true;
        }
    }
}

/**
 * The answer is true.
 * **/
  1. How much the answer is?
package cn.charliejohn.handlexexception;

public class Helloxexceptionx2 {
    public static void main(String[] args) {
        try{
            // 答:
            // 2. The answer is 0. Because the i in finally is another i.
            System.out.println("The answer is " + sthStrange()+".");
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static int sthStrange(){
        int i = 0;
        try {
            i = i/0;
        } catch (Exception e) {
            e.printStackTrace();
            return i;
        } finally {
            ++i;
        }
        return 100;
    }
}

/**
 * java.lang.ArithmeticException: / by zero
 * 	at cn.charliejohn.handlexexception.Helloxexceptionx2.sthStrange(Helloxexceptionx2.java:18)
 * 	at cn.charliejohn.handlexexception.Helloxexceptionx2.main(Helloxexceptionx2.java:9)
 * The answer is 0.
 * **/
  1. 综合案例
package cn.charliejohn.handlexexception;

import java.io.*;

/**
 * 1. 主函数catch块中抓到的是哪个异常?
 * 2. sthStrange的结果是多少?
 * 3. sthDangerous会抛出"Not important."异常吗?
 * **/
public class Hixexception
{
    // The exception throws in main is because
    // there is throws in finally.
    public static void main(String[] args) throws Exception {

        try{
            // The answer is 1, because the i in finally is another i;
            System.out.println("The answer is " + sthStrange());
        }catch(Exception e){
            // The exception handle by sthStrange itself,
            // so there is not exception from main.
            System.out.println("Exception from main");
            e.printStackTrace();
        }finally {
            // Call sthDangerous to prove that
            // return in finally will blocks exception in try.
            System.out.println(sthDangerous());
            System.out.println("Finally from main");
        }
    }

    /**
     * Sth strange happen when transmit i.
     * @return
     */
    public static int sthStrange(){
        int i = 0;
        OutputStream out = null;
        try {
            int j = 0;
            out = new FileOutputStream("D://nothing.md");
            // Exception occurs.
            j = j / 0;
            System.out.println("Try in sthStrange.");

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Catch in sthStrange.");
            return i;
        } finally {
            try {
                if (out != null) {
                    System.out.println("Finally try in sthStrange.");
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("Finally in sthStrange.");
            ++i;
        }
        return 100;
    }

    /**
     * Sth dangerous happen when finally return.
     * @return
     */
    public static boolean sthDangerous() throws Exception{
        try {
            // This exception will no be taken into account.
            // Because it will be blocked by finally return.
            throw new Exception("Not important.");
        } finally {
            System.out.println("Finally in sthDangerous.");
            return false;
        }
    }
}

/**
 * java.lang.ArithmeticException: / by zero
 *  at cn.charliejohn.handlexexception.Hixexception.sthStrange(Hixexception.java:40)
 *  at cn.charliejohn.handlexexception.Hixexception.main(Hixexception.java:17)
 * Catch in sthStrange.
 * Finally try in sthStrange.
 * Finally in sthStrange.
 * The answer is 0
 * Finally in sthDangerous.
 * false
 * Finally from main
 *
 * Process finished with exit code 0
 * **/

文件输出:

mdfile

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

charliejohn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值