Java异常处理之捕获异常

一、try-catch语句

捕获异常是通过try-catch语句实现的,最基本try-catch语句语法如下:

try{ //可能会发生异常的语句
} catch(Throwable e){ //处理异常e
}

1.try代码块

try代码块中应该包含执行过程中可能会发生异常的语句。一条语句是否有可能发生异常,这要 看语句中调用的方法。
如下:

public Date parse(String source) throws ParseException

方法后面的throws ParseException说明:当调用parse()方法时有可以能产生ParseException异常。
提示:静态方法、实例方法和构造方法都可以声明抛出异常,凡是抛出异常的方法都可以 通过try-catch进行捕获,当然运行时异常可以不捕获。一个方法声明抛出什么样的异常需要 查询API文档。

2.catch代码块

每个try代码块可以伴随一个或多个catch代码块,用于处理try代码块中所可能发生的多种异常。 catch(Throwable e)语句中的e是捕获异常对象,e必须是Throwable的子类,异常对象e的作用域在 该catch代码块中。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//try-catch代码块
public class HelloWorld {
    public static void main(String[] args) {
        Date date = readDate();
        System.out.println("日期="+date);
    }
//    定义了一个静态方法来将字符串解析成日期
    public static Date readDate(){
        try {
            String str = "2020-2-9";
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//            从字符串中解析日期,解析方法可能有发生ParseException异常
            Date date = dateFormat.parse(str);
            return date;

        } catch (ParseException e) {
            System.out.println("处理ParseException异常");
//            e.printStackTrace()是打印异常堆栈跟踪信息
            e.printStackTrace();
        }
        return null;
    }
}

运行结果:

日期=Sun Feb 09 00:00:00 CST 2020

Process finished with exit code 0

二、多catch代码块

如果try代码块中有很多语句会发生异常,而且发生的异常种类又很多。那么可以在try后面跟有多个catch代码块。多catch代码块语法如下:

try{ //可能会发生异常的语句
} catch(Throwable e){ //处理异常e
} catch(Throwable e){ //处理异常e
} catch(Throwable e){ //处理异常e
}

注意:在多个catch代码情况下,当一个catch代码块捕获到一个异常时,其他的catch代码块就不再进行匹配。当捕获的多个异常类之间存在父子关系时,捕获异常顺序与catch代码块的顺序有关。一般 先捕获子类,后捕获父类,否则子类捕获不到。
代码如下:

import java.io.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//多catch代码块
public class HelloWorld1 {
    public static void main(String[] args) {
        Date date = readDate();
        System.out.println("日期="+date);

    }
    public static Date readDate(){
        FileInputStream readfile = null;
        InputStreamReader ir = null;
        BufferedReader in = null;
        try {
//            调用FileInputStream()构造方法可能会发生FileNotFoundException异常
            readfile = new FileInputStream("readme.txt");
            ir = new InputStreamReader(readfile);

            in = new BufferedReader(ir);
//            读取文件中的一行数据, 调用BufferedReader输入流的readLine()方法可能会发生IOException异常
            String str = in.readLine();
            if (str == null){
                return null;
            }
//            调用SimpleDateFormat()方法可能会发生ParseException异常
            DateFormat df  = new SimpleDateFormat("yyyy-MM-dd");
            java.util.Date date = df.parse(str);
            return date;
//          应该先捕获FileNotFoundException异常后捕获IOException(先捕获子类异常)
        } catch (FileNotFoundException e) {
            System.out.println("处理FileNotFoundException");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("处理IOException");
            e.printStackTrace();
        } catch (ParseException e) {
            System.out.println("处理ParseException");
            e.printStackTrace();
        }
        return null;
    }
}

运行结果:

处理FileNotFoundException
日期=null
java.io.FileNotFoundException: readme.txt (No such file or directory)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(FileInputStream.java:195)
	at java.io.FileInputStream.<init>(FileInputStream.java:138)
	at java.io.FileInputStream.<init>(FileInputStream.java:93)
	at 异常处理类.捕获异常.HelloWorld1.readDate(HelloWorld1.java:29)
	at 异常处理类.捕获异常.HelloWorld1.main(HelloWorld1.java:19)

如果将FileNotFoundException和IOException捕获顺序调换,代码如下:

try{ 
//可能会发生异常的语句
} catch (IOException e) { 
// IOException异常处理
} catch (FileNotFoundException e) { 
// FileNotFoundException异常处理
}

那么第二个catch代码块永远不会进入,FileNotFoundException异常处理永远不会执行。 由于上述代码ParseException异常与IOException和FileNotFoundException异常没有父子关系,捕获ParseException异常位置可以随意放置。

三、try-catch语句嵌套

代码如下:

import java.io.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//try-catch语句嵌套
public class HelloWorld2 {
    public static void main(String[] args) {
        Date date = redaDate();
        System.out.println("日期="+date);

    }
    public static Date redaDate(){
        FileInputStream readfile = null;
        InputStreamReader ir = null;
        BufferedReader in = null;
        try {
//            调用FileInputStream()构造方法可能会发生FileNotFoundException异常,如果外层出现异常先捕获外层异常
            readfile = new FileInputStream("readme.txt");
            ir = new InputStreamReader(readfile);
            in = new BufferedReader(ir);
            try {
//            读取文件中的一行数据, 调用BufferedReader输入流的readLine()方法可能会发生IOException异常
                String str = in.readLine();
                if(str == null){
                    return null;
                }
//                调用SimpleDateFormat()方法可能会发生ParseException异常
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date date = dateFormat.parse(str);
                return date;
            } catch (ParseException e) {
                System.out.println("处理ParseException");
                e.printStackTrace();
            } catch (IOException e) {
                System.out.println("处理IOException");
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            System.out.println("处理FileNotFoundException");
            e.printStackTrace();
        }
        return null;
    }
}

总结:程序执行时外层捕获到异常,其他的catch代码块就不再进行匹配。若外层没有捕获到异常则捕获内层异常,程序执行时内层如果会发生异常,首先由内层catch进行捕获,如果捕获不到,则由外层catch捕获。

四、多重捕获

1.为什么使用多重捕获

多catch代码块客观上提高了程序的健壮性,但是程序代码量大大增加。如果有些异常虽然种类不同,但捕获之后的处理是相同的,看如下代码。

try{ 
//可能会发生异常的语句
} catch (FileNotFoundException e) { 
//调用方法methodA处理
} catch (IOException e) { 
//调用方法methodA处理
} catch (ParseException e) {
//调用方法methodA处理
}

2.如何使用多重捕获

Java 7推出了多重捕获(multi-catch)技术,可以帮助解决此类问题,上述代码修改如下:

try{ 
//可能会发生异常的语句
} catch (IOException | ParseException e) { 
//调用方法methodA处理
}

在catch中多重捕获异常用“|”运算符连接起来。
注意 :什么不写成FileNotFoundException | IOException | ParseException 呢?这是因 为由于FileNotFoundException属于IOException异常,IOException异常可以捕获它的所有子类异常了。
以上内容仅供参考学习,如有侵权请联系我删除!

发布了69 篇原创文章 · 获赞 7 · 访问量 3340

猜你喜欢

转载自blog.csdn.net/weixin_45366499/article/details/104248589