目录
- 一、try-catch语句
- 1.try代码块
- 2.catch代码块
- 二、多catch代码块
- 三、try-catch语句嵌套
- 四、多重捕获
- 1.为什么使用多重捕获
- 2.如何使用多重捕获
一、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异常可以捕获它的所有子类异常了。
以上内容仅供参考学习,如有侵权请联系我删除!